简体   繁体   English

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

[英]python launch/wait on “paired” processes in parallel (probably popen/wait/subprocess?)

I'm reasonably sure some functionality already exists to do this, but I haven't been able to find it. 我可以肯定地确定已经有一些功能可以执行此操作,但是我找不到它。 What I'm basically trying to do is what we'd write in BASH as: 我基本上想做的是用BASH编写为:

( sleep 1; echo "one" ) &
( sleep 2; echo "two" ) &
( sleep 3; echo "three" ) &
( sleep 4; echo "four" ) &

and have the entire thing execute in four seconds (not ten seconds)... 并在四秒钟(而不是十秒钟)内执行整个操作...

More generally, consider the case where I have a long list of processes that I need to run: (A1, B1, C1, D1 ...). 更一般而言,考虑以下情况:我需要运行一长列进程:(A1,B1,C1,D1 ...)。 I also have a list of "paired" processes, let's call them (A2, B2, C2, D2...) When any 'x1' processes finishes, I want to launch the corresponding 'x2' process, but I want to have all the x1 processes start in parallel, and as each one finishes I want the x2 process to be launched. 我也有一个“成对”进程的列表,我们称它们为(A2,B2,C2,D2 ...)当任何“ x1”进程完成时,我想启动相应的“ x2”进程,但是我想拥有所有x1进程都是并行启动的,每个进程完成后,我都希望启动x2进程。

I've figured out how to use subprocess.Popen, push each instance into a list, and then wait on all of those to finish, but I've only been able to wait on the entire initial set, and THEN fire off the second set. 我已经弄清楚了如何使用subprocess.Popen,将每个实例推送到一个列表中,然后等待所有实例完成,但是我只能等待整个初始集合,然后触发第二个实例组。 This is better, but not ideal by any stretch. 这样比较好,但无论如何都不理想。 This seems like something that shouldn't be too terribly hard, but I haven't been able to find it. 这似乎不应该太难,但我一直没能找到。

Another way to think about this is that if I have ten paired processes, immediately after invocation I'll have ten running processes, and ten OTHER processes each waiting on one of the first ten to finish. 考虑这一点的另一种方法是,如果我有十个成对的进程,那么在调用之后,我将立即有十个正在运行的进程,以及十个其他进程,每个进程都等待前十个进程之一完成。

(This actually needs to solve a larger, more general problem but once I can solve this case I can generalize and scale it...) (这实际上需要解决一个更大,更一般的问题,但是一旦我解决了这种情况,就可以将其概括和扩展...)

You can solve this in Python in many different ways. 您可以使用多种方法在Python中解决此问题。 Here are three obvious ones: 这是三个显而易见的:

  • The same way the shell solves it. 外壳解决问题的方式相同。 This is probably the easiest, at least on a Unix-like system, but it enforces some separation you may not want and does not work on Windows. 至少在类似Unix的系统上,这可能是最容易的,但是它会强制执行一些您可能不需要的分隔,并且在Windows上不起作用。
  • Through polling. 通过投票。 If you have nothing to do while polling, this may be a waste of system resources. 如果您在轮询时无事可做,可能会浪费系统资源。
  • Through threading. 通过线程。 This is the lightest weight, but also the trickiest to get right. 这是最轻的重量,也是最正确的选择。

The way the shell handles this is that: Shell处理此问题的方式是:

( sleep 1; echo "one" ) &

forks off a sub-shell. 分叉一个子壳。 The sub-shell forks off a sub-sub-shell, and the sub-sub-shell exec s the sleep 1 . 子外壳派生出一个子子外壳,并且子子外壳exec sleep 1 The first sub-shell now waits for the second sub-shell, and when that finishes, execs (no fork required this time) echo "one" . 现在,第一个子Shell等待第二个子Shell,完成后,execs(这次无需派生) echo "one" (Meanwhile the main shell does not wait at all.) (与此同时,主外壳根本不等待。)

Note that the number of processes here was 3: the main shell, the sub-shell, the sub-sub-shell which became the first echo, and then the first sub-shell became the second echo. 请注意,此处的进程数为3:主外壳,子外壳,子子外壳,它们成为第一个回显,然后第一个子外壳成为第二个回显。 The main shell can wait for, and hence get the result-status of, the first sub-shell, but it cannot see the sub-sub-shell at all. 主外壳程序可以等待并因此获得第一个子外壳程序的结果状态,但是它根本看不到该子子外壳程序。

To do this directly in Python, either call a shell to run your two commands in sequence—this shell will fork once for the first command, then run the second directly—or use os.fork() . 要直接在Python中执行此操作,请调用外壳程序以依次运行您的两个命令(此外壳程序将为第一个命令派生一次,然后直接运行第二个命令),或使用os.fork() If you're the child of the fork, use subprocess (with .call or .Popen or whatever) to run the first command, then use os.exec to runs the second command. 如果你叉的孩子,用subprocess (与.call.Popen或其他)运行的第一个命令,然后使用os.exec来运行第二个命令。 Alternatively, you can add yet more processes, and/or use multiprocessing (which adds a fancy communications mechanism between your various Python processes, so that you can do a lot more useful things, but it's even heavier-weight). 或者,您可以添加更多的进程,和/或使用multiprocessing (这将在您的各种Python进程之间添加一种奇特的通信机制,以便您可以做更多有用的事情,但它的重量甚至更大)。

To use polling, note that a subprocess.Popen instance has a poll method. 要使用轮询,请注意subprocess.Popen实例具有poll方法。 Call this to tell whether the process is still running, or has finished. 调用此命令可告诉该进程是否仍在运行或已完成。

To use threading, spin up threads that invoke subprocess.Popen and/or that invoke the .wait method on the created subprocess and then spin up the next one in the chain. 使用螺纹,旋转起来的是调用线程subprocess.Popen和/或调用.wait上所创建的子方法,然后旋转起来在链中的下一个。 You'll need to add your own locking around any variables shared across the various threads (such as the various work-lists—it may make sense to divide them up before spinning up the threads, so that each thread has a private work-list and merely contributes the final results, if any, under a lock). 您需要在各个线程(例如各个工作列表)之间共享的任何变量周围添加自己的锁定,在旋转线程之前将它们分开很有意义,以便每个线程都有一个私有工作列表并且仅在锁定状态下贡献最终结果(如果有)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Python 子进程的异步执行。Popen with wait() - Asynchronous execution of Python subprocess.Popen with wait() Python subprocess.Popen.wait(Popen) 不将输出重定向到文件 - Python subprocess.Popen.wait(Popen) not redirecting output to file 尽管调用了subprocess.Popen.wait(),由Python的子进程模块创建的进程是否仍有可能用完内存(是僵尸)? - Is it possible that processes created by subprocess module in Python still use up memory (are zombies), although subprocess.Popen.wait() was called? Python:将子进程作为守护程序启动,然后等待启动 - Python: Launch subprocess as daemon and wait for start Python:并行运行 2 个进程,然后等待所有进程超时 - Python: Run 2 processes in parallel then wait for all with timeout Python子进程Popen.terminate()仍然停留在wait() - Python subprocess Popen.terminate() still stuck on wait() Python subprocess.Popen.wait()返回0,即使发生错误 - Python subprocess.Popen.wait() returns 0 even though an error occured Subprocess.Popen等到孩子完成 - Subprocess.Popen wait untill the child finish Python-执行并行延迟子流程而不等待的简单方法 - Python - Simple way to do parallel delayed subprocess and not wait 带有Pygame的Python subprocess.Popen(),如何告诉Pygame等到子进程完成 - Python subprocess.Popen() with Pygame , how to tell Pygame wait untill subprocess is done
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM