python多进程不同实现方法的异同点

更多内容,请访问 bbhhhh.github.io       

最近一直在用python编写大数据分析程序,其中用到了多进程的技术,python实现多进程有多种方法,不同方法的运行效果不尽相同,通过这两天的测试整理,虽然不一定很全面,但有些内容python官方文档也没有涉及,因此赶紧写下来方便以后使用,同时也供大家参考,不正确的地方也请指出。

        Python实现多进程主要有以下三种方法:

        1. 使用multiprocessing.Process()

        2. 使用os.fork() (仅Unix)

        3. 使用subprocess.Popen()

 

1. multiprocessing.Process() 创建的子进程

1)如果子进程的daemon=False或默认,如果有子进程未结束,即使主进程的所有逻辑已完成,也必须等  到子进程结束后才能退出。

2)如果子进程的daemon=True,一旦主进程的所有逻辑已经完成,主进程会立即终止仍在运行的子进程,并退出。

3)无论子进程daemon=True or False

向主进程发送SIGTERM 或 SIGKILL 信号, 主进程停止,子进程不受影响继续运行。

向子进程发送SIGTERM 或 SIGKILL 信号, 子进程停止,主进程不受影响继续运行。

4)关于Zombie僵尸进程

如果子进程自行结束或被其他进程(包括主进程)kill或terminate,而主进程仍然在运行,并且主进程中未调用过os.wait()或os.waitpid()或子进程的join()方法,该子进程将进入僵尸状态(通过 ps命令,状态显示为Z)直到主进程结束。
    
CAUTION: 如果子进程daemon=True, 主进程中调用os.wait() or os.waitpid() 会在退出时产生OSError exception ([Errno 3] No such process),但调用join()方法没问题,不清楚为什么。

 

 

2. os.fork() 创建的子进程

1)如果主进程的所有逻辑已完成,不需要等待子进程结束就能退出。

2)主进程退出后,不影响子进程的运行状态。

3)如果子进程代码块后面还有代码,这部分代码会被执行2次,一次是主进程执行的,一次是子进程结束后执行的。比如,下面的“parent”会被输出2次。

 

	pid=os.fork()
	if pid==0: # child
		print("forked child")
	print("parent")

为避免这种情况,可以这样写:

 

 

	pid=os.fork()
	if pid==0: # child
		print("forked child")
	else:
                print("parent")

 

以上几点与Process()不同。

下面2点与Process()相同:

4)向主进程发送SIGTERM 或 SIGKILL 信号, 主进程停止,子进程不受影响继续运行。

向子进程发送SIGTERM 或 SIGKILL 信号, 子进程停止,主进程不受影响继续运行。

5)关于Zombie僵尸进程

如果子进程自行结束或被其他进程(包括主进程)kill或terminate,而主进程仍然在运行,并且主进程中未调用过os.wait()或os.waitpid()方法,该子进程将进入僵尸状态(通过 ps命令,状态显示为Z)直到主进程结束。

 

 

3. subprocess.Popen() 创建的子进程

1)如果主进程的所有逻辑已完成,不需要等待子进程结束就能退出。

2)主进程退出后,不影响子进程的运行状态。

 

以上几点与Process()不同。

 

下面2点与Process()相同:

 

3)向主进程发送SIGTERM 或 SIGKILL 信号, 主进程停止,子进程不受影响继续运行。

      向子进程发送SIGTERM 或 SIGKILL 信号, 子进程停止,主进程不受影响继续运行。

4)关于Zombie僵尸进程

如果子进程自行结束或被其他进程(包括主进程)kill或terminate,而主进程仍然在运行,并且主进程中未调用过os.wait()或subprocess.wait()或subprocess.communicate(),该子进程将进入僵尸状态(通过 ps命令,状态显示为Z)直到主进程结束。

 

       最后说一下os._exit()和sys.exit()两个方法产生的不同结果:

       A进程调用os._exit()方法后产生的效果等同于向A进程发送SIGTERM或SIGKILL信号。

        A进程调用sys.exit()方法后产生的效果等同于A进程代码执行完毕,自行结束。

        因此,针对上面的第1类子进程,如果主进程调用了os._exit()方法,主进程立即退出,且不影响子进程的运行。如果调用了sys.exit(),主进程停止运行,如果子进程daemon=False,需等待子进程结束后才能退出;如果子进程daemon=True,则终止子进程并退出。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值