我正在使用子进程Popen执行一个第三方应用程序,其中有许多参数
myprocess=Popen(['executionlist','with','arguments'],stdout=PIPE,stderr=PIPE)
myprocess.communicate()
在获取stdout和err的元组时,第三方应用程序在后台启动,因此我在stdout中获取其pid…[如果我尝试在forgound中运行,它将抛出“Error opening terminal:unknown”] 我用psutil来跟踪所有这些分叉并用
^{pr2}$应用程序发送不同的退出代码,我需要在EXITCODE中访问这些代码,但是当我在不同的python脚本中运行它时,它总是给我一个'None'值。。。。在
根据, https://code.google.com/p/psutil/wiki/Documentation Wait()表示进程终止,如果该进程是当前进程的子进程,则返回退出代码,否则无
不管怎样,我能从独立进程id(不是Popen专门派生的)访问出口代码吗?在
您引用的文档告诉您,
psutil
只能获得退出代码“如果进程是当前进程的子进程”。在这才是真正的关键所在–不是进程是否由
Popen
启动,而是它是否是当前进程的子进程。*这是Unix进程模型的基础。父母必须等孩子。你不能让别人等他们(除非通过重新租用)。如果父母还在跑步,那就必须是收获它们的人。如果父级不再运行,则可能是子级已经是僵尸,或者它被重新租给父级的父级或init/launchd/etc.或者被孤立(在不同的系统和不同的情况下,细节是不同的)。没有其他进程可以等待它们的情况。在
除此之外,一旦父进程调用
wait
(这是Popen.communicate
所做的),进程及其在系统进程表中的条目及其retcode可能不再存在。在*也就是说,即使您没有跨进程,将})混合使用也是个坏主意。如果创建一个}创建的进程,但不能使用
subprocess
与低级api(如os
或{Popen
对象,则必须调用它的wait
方法,或其他类似于communicate
的方法。一旦你这样做了,它可能就不复存在了。如果要使用os.wait
,请使用os
中的fork/spawn/etc.methods创建的进程。如果要使用psutil.wait
,可以使用由os
或{subprocess.Popen
。在在反复讨论了一些评论之后,我怀疑你实际上是想做这样的事情:
在你的主程序中,“启动并忘记”一些后台进程。但稍后,在同一个程序中,每当每个进程实际完成时,运行一些代码,以访问进程的返回代码(可能还有输出)。在
下面是一个这样做的例子,通过对每个后台进程使用一个watcher线程:
这有两个明显的局限性,但最终它们与您在尝试(例如,在internet上同时与多台计算机通信)时遇到的相同的多路复用问题,而且它们有相同的解决方案。在
首先,拥有数百个线程是不好的。它们不做任何事情,但它们仍然有很大的堆栈,占用了虚拟内存空间(在32位Python中尤其糟糕),并占用内核调度表中的空间(在旧unix中尤其糟糕)。幸运的是,如果您不关心Windows,您可以用处理网络代码的方法来解决这个问题:将子进程管道放入
select
或poll
循环中。或者,如果您不关心Windows,或者不想编写自己的select
循环,请找到一个框架来为您完成所有的重担。如果您search PyPI for "subprocess",您将找到一些特定于subprocess
的选项。如果您已经在使用一个事件驱动的网络或GUI框架,比如Twisted或Qt,那么它很可能有自己的方法来实现这一点(例如,请参见Twisted的Using Processes)。在第二,您的
callback
在某个任意的后台线程中被调用,并且除了改变一些共享值之外,无法将返回值或异常传播到代码的其余部分。这意味着您现在正在处理共享数据线程的所有常见问题,尽管您从未要求这样做。所有改善这种情况的常用方法-queue
,concurrent.futures
等等——在这里也适用。在当然,如果幸运的话,一次只能运行十几个进程(所以第一个问题不是问题),而在回调中您只想打印或记录一些数据(所以第二个问题不是问题)。在
相关问题 更多 >
编程相关推荐