Python在一个线程中调用pipe.communicate()

时间:2010-03-30 02:05:01

标签: python multithreading deadlock multiprocessing

在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)时,代码运行得很好。

对于为何阻止以及如何修复的任何想法都将不胜感激。

谢谢。

2 个答案:

答案 0 :(得分:1)

使用多个线程多个进程通常会导致问题,特别是(但不是唯一的)基于Unix的系统;我建议你不要混淆两者。

答案 1 :(得分:1)

如果在主线程中调用sys.exit(),其他线程将在下次机会时终止(在大多数操作系统上)。但是,如果它们处于阻塞调用(例如communic()),它们将等待阻塞调用完成后再终止。 Control-C有效,因为它会导致操作系统中断阻塞调用。

通常,最安全的方法是确保没有任何线程调用可能无限期阻塞的函数。不幸的是,这通常涉及编写更多代码。

在您的特定情况下,您可以在调用通信之前将Popen个对象存储在全局set()中,并在退出之前让每个主要线程调用Popen.terminate()。这将导致孩子退出,communicate()返回,并退出线程。

您是将线程设置为daemon线程吗?