在等待读取很长时间时杀死python线程

时间:2016-08-06 08:07:38

标签: python multithreading

我需要终止线程但是不能定期检查任何标志,因为它等待读/输入。

简单示例:

import threading, time

class Test(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)

    def run(self):
        print(input("wainting for input: "))

th = Test()
th.start()
time.sleep(5)
print("killing!")
th.join(5)
print(th.is_alive())

更真实的例子就是这个(挂起时杀死线程 - 长时间无输出):

import threading, time

class Test(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)

    def call(args):
        return subprocess.Popen(" ".join(args), shell=True, stderr=subprocess.PIPE)     

    def run(self):
        mainProcess = call([ any program that could hang])
        out = None
        while mainProcess.returncode != 0 or out == '' and mainProcess.poll() != None:
            out = mainProcess.stderr.read(1)
            if out != '':
                sys.stdout.write(out)
                sys.stdout.flush()

th = Test()
th.start()
time.sleep(5)
print("killing!")
th.join(5)
print(th.is_alive())

如果有更好的方法,我也会很开心。

2 个答案:

答案 0 :(得分:1)

以下是一个示例,如何使用select解决挂起过程问题:

import threading
import select
import subprocess
import sys

def watch_output(args, timeout):
    process = subprocess.Popen(args, stdout=subprocess.PIPE)     
    while True:
        ready_to_read, _, _ = select.select([process.stdout], [], [], timeout)
        if not ready_to_read:
            print "hanging process"
            process.kill()
            break
        out = ready_to_read[0].read(1)
        if not out:
            print "normal exit"
            break
        sys.stdout.write(out)
        sys.stdout.flush()
    return process.wait()

watch_output(['ls'], timeout=10)

甚至可以输入超时:

def read_input(prompt, timeout):
    sys.stdout.write(prompt)
    sys.stdout.flush()
    ready_to_read, _, _ = select.select([sys.stdin], [], [], timeout)
    if not ready_to_read:
        return None
    return ready_to_read[0].readline()

print read_input("wainting for input (4s): ", 4)

答案 1 :(得分:0)

你可以让主线程杀死进程。读者线程最终会点击EOF然后退出。

示例:

#!/usr/bin/env python

import threading
import subprocess
import time
import sys

def pipe_thread(handle):
  print "in pipe_thread"
  x = handle.readline()
  while x:
    print "got:", x[:-1]
    x = handle.readline()

def main():
  p = subprocess.Popen(["./sender"], stdout = subprocess.PIPE)
  t = threading.Thread(target = pipe_thread, args = [p.stdout])
  t.start()

  print "sleeping for a while"
  time.sleep(5)
  print "killing process"
  p.kill()
  print "joining"
  t.join()
  print "joined"

main()