在Mac OS X 10.6.2上使用Python 2.6.1,我遇到以下问题:
我有一个线程进程(一个Thread类),每个线程都有一个管道(subprocess.Popen)喜欢的东西:
from threading import Thread
cmd = "some_cmd"
class Worker(Thread):
def run(self):
pipe = Popen(cmd,
stdin=PIPE,
stdout=PIPE,
stderr=PIPE)
out, err = pipe.communicate("some data")
问题是pipe.communicate()代码是阻塞的。有趣的是,当我向父进程发送一个中断(例如Ctrl-C
KeyboardInterrupt)时,它会解除阻塞。
有趣的是,当我使用class Worker(multiprocessing.Process)
时,代码运行得很好。
对于为何阻止以及如何修复的任何想法都将不胜感激。
谢谢。
答案 0 :(得分:1)
使用多个线程和多个进程通常会导致问题,特别是(但不是唯一的)基于Unix的系统;我建议你不要混淆两者。
答案 1 :(得分:1)
如果在主线程中调用sys.exit()
,其他线程将在下次机会时终止(在大多数操作系统上)。但是,如果它们处于阻塞调用(例如communic()),它们将等待阻塞调用完成后再终止。 Control-C有效,因为它会导致操作系统中断阻塞调用。
通常,最安全的方法是确保没有任何线程调用可能无限期阻塞的函数。不幸的是,这通常涉及编写更多代码。
在您的特定情况下,您可以在调用通信之前将Popen
个对象存储在全局set()
中,并在退出之前让每个主要线程调用Popen.terminate()
。这将导致孩子退出,communicate()
返回,并退出线程。
您是将线程设置为daemon线程吗?