更多内容,请访问 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,则终止子进程并退出。