Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/gwt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python启动/等待”;成对的;并行进程(可能是popen/wait/subprocess?)_Python_Subprocess_Wait - Fatal编程技术网

python启动/等待”;成对的;并行进程(可能是popen/wait/subprocess?)

python启动/等待”;成对的;并行进程(可能是popen/wait/subprocess?),python,subprocess,wait,Python,Subprocess,Wait,我有理由相信已经有一些功能可以做到这一点,但我还没有找到它。我基本上想做的是我们在BASH中写的: ( sleep 1; echo "one" ) & ( sleep 2; echo "two" ) & ( sleep 3; echo "three" ) & ( sleep 4; echo "four" ) & 让整个过程在四秒钟内完成(不是十秒钟) 更一般地,考虑一个我需要运行的长过程列表:(A1,B1,C1,D1……)。我还有一个“成对”进程的列表,让我们称

我有理由相信已经有一些功能可以做到这一点,但我还没有找到它。我基本上想做的是我们在BASH中写的:

( sleep 1; echo "one" ) &
( sleep 2; echo "two" ) &
( sleep 3; echo "three" ) &
( sleep 4; echo "four" ) &
让整个过程在四秒钟内完成(不是十秒钟)

更一般地,考虑一个我需要运行的长过程列表:(A1,B1,C1,D1……)。我还有一个“成对”进程的列表,让我们称之为(A2、B2、C2、D2…)当任何“x1”进程完成时,我想启动相应的“x2”进程,但我想让所有x1进程并行启动,当每个进程完成时,我想启动x2进程

我已经知道了如何使用subprocess.Popen,将每个实例推到一个列表中,然后等待所有实例完成,但我只能等待整个初始集合,然后启动第二个集合。这更好,但无论如何都不理想。这似乎不应该太难,但我一直没能找到

考虑这一点的另一种方式是,如果我有十个成对的进程,在调用之后,我将有十个正在运行的进程,还有十个其他进程,每个进程都在等待前十个进程中的一个完成


(这实际上需要解决一个更大、更一般的问题,但一旦我能解决这个问题,我就可以对它进行概括和扩展…

您可以用Python以多种不同的方式解决这个问题。这里有三个明显的例子:

  • 就像外壳解决它一样。这可能是最简单的,至少在类Unix系统上是如此,但它强制执行了一些您可能不希望也不适用于Windows的分离
  • 通过投票。如果在轮询时无事可做,这可能会浪费系统资源
  • 穿线。这是最轻的重量,但也是最难做到的
shell处理此问题的方式是:

( sleep 1; echo "one" ) &
分叉出一个外壳。子外壳分叉出一个子外壳,子外壳
exec
s
sleep 1
。第一个子shell现在等待第二个子shell,完成后,execs(这次不需要fork)
echo“one”
。(同时,主外壳根本不等待。)

请注意,这里的进程数为3:主壳、子壳、成为第一个回声的子壳,然后第一个子壳成为第二个回声。主shell可以等待并因此获得第一个子shell的结果状态,但它根本看不到该子shell

要在Python中直接执行此操作,可以调用一个shell以按顺序运行两个命令。此shell将为第一个命令分叉一次,然后直接运行第二个命令,或者使用
os.fork()
。如果您是fork的子进程,请使用
子进程
(使用
.call
.Popen
或其他命令)运行第一个命令,然后使用
os.exec
运行第二个命令。或者,您可以添加更多的进程,和/或使用
多处理
(这在各种Python进程之间添加了一种奇特的通信机制,这样您可以做更多有用的事情,但重量更重)

要使用轮询,请注意
subprocess.Popen
实例有一个
poll
方法。调用此函数可判断进程是否仍在运行,或是否已完成


要使用线程,请对调用
子流程.Popen
和/或调用所创建子流程上的
.wait
方法的线程进行加速,然后对链中的下一个线程进行加速。您需要在各个线程之间共享的任何变量周围添加您自己的锁定(例如各种工作列表,在旋转线程之前对它们进行划分可能是有意义的,这样每个线程都有一个私有工作列表,并且只在锁定下贡献最终结果(如果有的话)。

所以我有点像您在这里说的那样,但老实说,这其中的一些已经飞逝而去。shell方法的解释是有道理的,但如果我更一般的情况更像“我需要能够连续运行多个命令的多LPE组,这会改变我们的方法吗?在我的头脑中,我一直认为这应该是类似于“推送顺序A1、A2、A3的列表…”。。。要在列表中运行的命令,然后将另一组顺序B1 B2 B3命令推送到不同的列表上(以此类推),然后开始并行处理每个命令列表……让我们尝试另一个示例,shell样式:如果您事先知道要让Worker X运行命令X1,然后X2,然后X3:创建Worker X,让X运行X1并等待它。然后让X运行X2并等待它。然后让X运行X3,可能是通过exec。当这不起作用时:假设您知道希望X运行某些东西,但在X开始运行X1,Y开始并完成Y1和Y2之前,您不确定X是否应该运行X2a或X2b。这取决于Y1和Y2的结果。如果X独立于Y,X怎么知道Y看到了什么?