Python多重处理模块的.join()方法到底在做什么?

2020/11/30 16:41 · python ·  · 0评论

PMOTW文章中了解Python多重处理并且希望对方法的确切作用进行一些说明join()

2008年的旧教程中,它指出,没有p.join()以下代码中调用,“子进程将处于空闲状态而不会终止,成为必须手动杀死的僵尸”。

from multiprocessing import Process

def say_hello(name='world'):
    print "Hello, %s" % name

p = Process(target=say_hello)
p.start()
p.join()

我添加的打印输出PID,以及一个time.sleep测试,并就我所知道的,在自己的进程终止:

from multiprocessing import Process
import sys
import time

def say_hello(name='world'):
    print "Hello, %s" % name
    print 'Starting:', p.name, p.pid
    sys.stdout.flush()
    print 'Exiting :', p.name, p.pid
    sys.stdout.flush()
    time.sleep(20)

p = Process(target=say_hello)
p.start()
# no p.join()

20秒内:

936 ttys000    0:00.05 /Library/Frameworks/Python.framework/Versions/2.7/Reso
938 ttys000    0:00.00 /Library/Frameworks/Python.framework/Versions/2.7/Reso
947 ttys001    0:00.13 -bash

20秒后:

947 ttys001    0:00.13 -bash

行为与p.join()添加回文件末尾的行为相同本周Python模块提供了非常易读的模块解释; “要等到进程完成工作并退出后,请使用join()方法。”,但看来至少OS X仍在这样做。

我也想知道该方法的名称。.join()方法在此处串联吗?它是在连接过程的结尾吗?还是只是与Python的本地.join()方法共享一个名称

join()方法与threading或一起使用时multiprocessing,与之无关str.join()-实际上没有将任何东西串联在一起。相反,它仅表示“等待此[线程/进程]完成”。join之所以使用该名称,是因为该multiprocessing模块的API看起来类似于该threading模块的API,并且该threading模块join用于其Thread对象。join在许多编程语言中,使用该术语表示“等待线程完成”是很常见的,因此Python也采用了它。

现在,您看到有和没有调用都延迟20秒的原因join()是因为默认情况下,当主进程准备退出时,它将隐式调用join()所有正在运行的multiprocessing.Process实例。multiprocessing文档中并未对此进行明确说明,但在“编程指南”部分中进行了提及

还请记住,非守护进程将自动加入。

您可以通过设置覆盖此行为daemon上的标志ProcessTrue之前,要启动的过程:

p = Process(target=say_hello)
p.daemon = True
p.start()
# Both parent and child will exit here, since the main process has completed.

如果这样做,则子进程将在主进程完成后立即终止

守护程序

进程的守护程序标志,一个布尔值。必须在调用start()之前进行设置。

初始值是从创建过程继承的。

进程退出时,它将尝试终止其所有守护程序子进程。

没有join(),主进程可以在子进程之前完成。我不确定在什么情况下会导致僵尸。

的主要目的join()是确保子流程在主流程执行任何依赖于子流程的工作之前完成。

的词源join()与相对fork,后者是Unix系列操作系统中用于创建子进程的常用术语。单个过程“分叉”成多个,然后“连接”成一个。

我不会详细解释join它的作用,但是这里是其词源和直觉,这应该有助于您更轻松地记住其含义。

这个想法是执行“分叉”到多个进程中,其中一个是主进程,其余是工人(或“奴隶”)。工作人员完成后,他们会“加入”主服务器,以便可以恢复串行执行。

join方法使主进程等待工作人员加入。该方法最好称为“等待”,因为这是它在主服务器中引起的实际行为(这就是POSIX中所称的内容,尽管POSIX线程也称其为“ join”)。连接仅是由于线程正确协作而产生的,而不是主机执行的操作

自1963年以来,名称“ fork”和“ join”已在多处理中使用此含义

join()调用可确保在完成所有多处理过程之前不会调用代码的后续行。

例如,如果没有使用join(),则restart_program()甚至在进程完成之前,也会调用以下代码,这类似于异步,不是我们想要的(您可以尝试):

num_processes = 5

for i in range(num_processes):
    p = multiprocessing.Process(target=calculate_stuff, args=(i,))
    p.start()
    processes.append(p)
for p in processes:
    p.join() # call to ensure subsequent line (e.g. restart_program) 
             # is not called until all processes finish

restart_program()

join()用于等待辅助进程退出。必须先致电close()terminate()使用join()

就像@Russell提到的那样,join就像fork的反义词Spawns子流程)。

要运行加入,您必须先运行close(),这将阻止所有其他任务提交到池中,并在所有任务完成后退出。或者,terminate()通过立即停止所有工作进程退出运行

"the child process will sit idle and not terminate, becoming a zombie you must manually kill" 当主(父)进程退出但子进程仍在运行并且完成后,它没有父进程可以将其退出状态返回时,这是可能的。

要等待进程完成其工作并退出,请使用join()方法。

注意终止进程后,必须对join()进程进行处理,以便让后台设备有时间更新对象的状态以反映终止。

这是一个很好的例子,帮助我理解了:这里

我个人注意到的一件事是,我的主要过程暂停了,直到孩子使用join()方法完成了过程,这首先挫败了我的使用multiprocessing.Process()意图。

本文地址:http://python.askforanswer.com/pythonduozhongchulimokuaide-joinfangfadaodizaizuoshenme.html
文章标签: ,  
版权声明:本文为原创文章,版权归 admin 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!