我有一个Python多处理应用程序,使用多处理API启动“工作人员”。 主进程本身是由一个不是用Python编写的服务进程启动的。 工作人员可能使用subprocess.Popen
自己启动其他非Pythonsubprocess。
为了清楚起见,这是整个stream程层次结构:
当服务进程停止时,它必须告诉Python进程退出。 我正在使用标准input。 其优点是,如果服务进程崩溃或被终止,那么Python进程的标准input被closures,所以它将退出,并且将不会有孤立进程。
import multiprocessing import time import sys def task(): print("Task started...") # TODO: Start a native process here using Subprocess.popen time.sleep(3) print("Task ended") if __name__ == '__main__': process = multiprocessing.Process(target=task) process.start() # time.sleep(3) # "workaround" sys.stdin.read() print("Terminating process...") process.terminate()
但是,似乎当我添加sys.stdin.read()
,Pythonsubprocess启动,但它什么都不做。 它似乎挂起。
(坏)解决方法是在从标准input读取之前添加time.sleep(3)
。 然后上面的程序工作。 但是,看起来Pythonsubprocess启动的subprocess仍然可以阻塞,只有在主进程中进行阻塞读取时,它们才会阻塞。
所有系统上都不会发生此问题。 它在一台Windows 8机器上被观察到,并且从未在另一台Windows机器上发生过。 我正在使用Python 2.7.2。
我的问题是:如何在主进程阻塞读取影响subprocess? 子stream程不应该独立于我在主stream程中做的任何事情吗? (我只想了解这个问题,如果你find一个更好的解决scheme来停止服务进程中的Python进程,我会很感激,但这是一个奇怪的阻塞行为,给了我恶梦)
你的子进程不挂。 当我使用多处理库时,我最喜欢使用的调试技术之一是使子进程删除文本文件,而不是打印到标准输出,这样可以避免管道的所有复杂问题,比如想知道子进程是否继承相同的标准输入/标准输出,完整的管道等。如果我们将您的任务修改为以下内容:
def task(): with open('taskfile.txt', 'w') as fo: fo.write("Task started...") # TODO: Start a native process here using Subprocess.popen time.sleep(3) fo.write("Task ended")
它生成包含以下内容的文本文件“taskfile.txt”:
任务开始…任务结束
因此,你的任务正在运行,退出就好了。 Main只是等待来自stdin的输入。 我怀疑你没有看到“Task started …”的提示,因为使用multiprocessing.Process()
启动的进程有自己的stdin和stdout管道,这些管道没有连接到与main相同的控制台。