python在“配对”进程上并行启动/等待(可能是popen / wait / subprocess?)

时间:2018-12-29 00:36:33

标签: python subprocess wait

我可以肯定地确定已经有某些功能可以执行此操作,但是我找不到它。我基本上想做的是我们用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,将每个实例推送到一个列表中,然后等待所有实例完成,但是我只能等待整个初始集合,然后触发离开第二组。这样比较好,但无论如何都不理想。这似乎不应该太难,但我一直没能找到。

另一种思考方式是,如果我有十个成对的进程,则在调用后立即有十个正在运行的进程,还有十个其他进程,每一个都在等待前十个进程之一完成。

(这实际上需要解决更大,更笼统的问题,但是一旦我解决了这种情况,就可以将其概括和扩展...)

1 个答案:

答案 0 :(得分:1)

您可以使用多种方法在Python中解决此问题。这是三个明显的例子:

  • 外壳解决问题的方法相同。至少在类似Unix的系统上,这可能是最简单的方法,但是它会强制执行一些您可能不需要的分隔,并且在Windows上不起作用。
  • 通过轮询。如果您在轮询时无事可做,可能会浪费系统资源。
  • 通过线程。这是最轻的重量,也是最正确的重量。

shell处理此问题的方式是:

( sleep 1; echo "one" ) &

分叉出子壳。子外壳派生出一个子子外壳,子子外壳exec成为sleep 1。现在,第一个子Shell等待第二个子Shell,完成后,执行程序(这次不需要派生)echo "one"。 (与此同时,主外壳根本不等待。)

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

要直接在Python中执行此操作,请调用外壳程序以依次运行您的两个命令(此外壳程序将为第一个命令派生一次,然后直接运行第二个命令)或使用os.fork()。如果您是fork的孩子,请使用subprocess(与.call.Popen或其他任何命令一起运行第一个命令,然后使用os.exec运行第二个命令。另外,您可以添加更多的进程,和/或使用multiprocessing(这将在您的各种Python进程之间添加一种奇特的通信机制,以便您可以做更多有用的事情,但是它甚至更重)。

要使用轮询,请注意subprocess.Popen实例具有一种poll方法。调用此命令可告诉该进程是否仍在运行或已完成。

要使用线程,请旋转在创建的子进程上调用subprocess.Popen和/或调用.wait方法的线程,然后旋转链中的下一个线程。您需要在各个线程(例如各个工作列表)之间共享的所有变量周围添加自己的锁定,在旋转线程之前将它们分开很有意义,以便每个线程都有一个私有工作列表并且仅在锁定状态下提供最终结果(如果有)。