繁体   English   中英

如何在python中使用多处理正确终止子进程

[英]How to properly terminate child processes with multiprocessing in python

我有几个回调函数,我想启动多个进程,并通过父进程的信号终止它们。

我目前的做法是创建一个带有multiprocessing.Value的共享c_bool并将其设置为True ,然后在创建它们时将其分发给我的所有进程。 我的进程都使用共享bool运行while循环,如下所示:

while myC_bool: ...keep running...

然后,我可以从我的父进程将bool切换为False ,并且所有子进程将完成其最终循环并退出。

许多人都告诉我,并且已经在文档中读到,在使用多处理时应该尝试避免使用共享内存。 我被告知避免这种情况的最佳方法是守护进程,给它一个自定义信号处理程序并发送一个sigint / sigterm / etc ......

我的问题是,是专门使用bool来保持循环活动,并且只是从我的父进程改变它的值,并从多个子进程读取一个合适的解决方案,以使我的所有子进程快速安全地终止? 我觉得所有孩子只需要查看一个共享bool就可以减少开销,而不是向他们发送x个sigints。

守护是否会成为更好的解决方案? 如果是这样,我想帮助理解为什么。

您的解决方案有很多很好的理由:

  • 思考比信号更容易。
  • 它需要处理的跨平台问题较少。
  • 你已经有了以这种方式工作的代码。
  • 如果您希望将来添加“正常关闭”机制,则可以轻松添加。

… 等等。

请记住,除非你能够证明你所关心的每个平台上的multiprocessing和底层操作系统原语都保证在没有同步的情况下工作,你需要在每次访问共享bool时放置一个Lock或其他东西。 。 这并不是很复杂,但是......一旦你完成了这一点,使用例如没有共享bool的Event可能会更简单。

无论如何,如果有任何这些是你的理由,我会说很好,就这样做。 但根据你的问题,你实际上是因为性能而选择了这个:

我觉得所有孩子只需要查看一个共享bool的开销就少了,而不是向他们发送x个sigints

如果这是你的理由,你几乎肯定是错的。 孩子们每次通过一些循环都必须查看共享bool(并获取共享锁!),而信号只需要发送给每个孩子一次。 所以,你的开销几乎肯定会高得多。

但实际上,我无法想象每个子进程发送一个信号的开销,甚至每个进程每个循环抓取一次进程间锁定的开销,在任何有用的程序中都是接近瓶颈的,所以......为什么这里的开销很重要首先? 以最简单的方式做最有意义的事情。

既然你要小心修改共享变量的人,那应该没问题。

有许多不同的解决方案可能。 例如,使用multiprocessing.Event ,并在进程设置时终止进程。 或者使用multiprocessing.Connection对象(来自Pipe)。 后者可用于父母与子女之间的双向沟通​​。 就像一个给孩子停下来的信号,然后向父母确认。

告诉你“不要这样做”的人是错的。 共享内存的关键是在多处理器之间共享内存,而这正是您正在做的事情。

你有一个解决方案1)很简单,2)工作。 信号/守护进程方法1)非常酷,2)更难以正确编码和3)更难理解。

我在你的方法中看到的唯一缺陷是一个进程可能从CPU的缓存中看到bool的陈旧副本,并在关闭时稍微延迟。 有一些方法可以刷新缓存以确保不会发生这种情况,但是您可能不需要它们,因为对于大多数应用程序来说,缓存刷新经常会自动发生。

坚守阵地。

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM