python之multiprocessing创建进程

python的multiprocessing模块是用来创建多进程的,下面对multiprocessing总结一下使用记录。

multiprocessing创建多进程在windows和linux系统下的对比

fork() import os pid = os.fork() # 创建一个子进程 if pid == 0: print('这是子进程') print(os.getpid(),os.getppid()) else: print('这是父进程') print(os.getpid()) os.wait() # 等待子进程结束释放资源

fork函数被调用后会返回两次,pid为0的代表子进程,其他返回子进程的id号表示父进程。

getpid和getppid函数可以获取本进程和父进程的id号;

fork方式的缺点:

兼容性差,只能在类linux系统下使用,windows系统不可使用;

扩展性差,当需要多条进程的时候,进程管理变得很复杂;

会产生“孤儿”进程和“僵尸”进程,需要手动回收资源。

优点:

是系统自带的接近低层的创建方式,运行效率高。

Process创建进程

创建方式一:

from multiprocessing import Queue, Process import os def test(): time.sleep(2) print('this is process {}'.format(os.getpid())) if __name__ == '__main__': p = Process(target=test) p.start() # 子进程 开始执行 p.join() # 等待子进程结束 print('ths peocess is ended')

创建方式二:

from multiprocessing import Queue, Process import os class MyProcess(Process): def run(self): time.sleep(2) print('this is process {}'.format(os.getpid())) def __del__(self): print('del the process {}'.format(os.getpid())) if __name__ == '__main__': p = MyProcess() p.start() print('ths process is ended') # 结果: ths process is ended this is process 7600 del the process 7600 del the process 12304

说明:

Process对象可以创建进程,但Process对象不是进程,其删除与否与系统资源是否被回收没有直接的关系。

上例看到del方法被调用了两次,Process进程创建时,子进程会将主进程的Process对象完全复制一份,这样在主进程和子进程各有一个Process对象,但是p1.start()启动的是子进程,主进程中的Process对象作为一个静态对象存在。

主进程执行完毕后会默认等待子进程结束后回收资源,不需要手动回收资源;

join()函数用来控制子进程结束的顺序,主进程会阻塞等待子进程结束,其内部也有一个清除僵尸进程的函数,可以回收资源;

当子进程执行完毕后,会产生一个僵尸进程,其会被join函数回收,或者再有一条进程开启,start函数也会回收僵尸进程,所以不一定需要写join函数。

windows系统在子进程结束后会立即自动清除子进程的Process对象,而linux系统子进程的Process对象如果没有join函数和start函数的话会在主进程结束后统一清除。

Process对象分析 class Process(object): def __init__(self, group=None, target=None, name=None, args=(), kwargs={}): pass # Process对象是python用来创建进程的类 group:扩展保留字段; target:目标代码,一般是我们需要创建进程执行的目标函数。 name:进程的名字,如果不指定会自动分配一个; args:目标函数的普通参数; kwargs:目标函数的键值对参数; # 方法 start():创建一个子进程并执行,该方法一个Process实例只能执行一次,其会创建一个进程执行该类的run方法。 run():子进程需要执行的代码; join():主进程阻塞等待子进程直到子进程结束才继续执行,可以设置等待超时时间timeout. terminate():使活着的进程终止; is_alive():判断子进程是否还活着。 进程池Pool

如果需要创建大量的进程,就需要使用Pool了。

from multiprocessing import Queue, Process, Pool import os def test(): time.sleep(2) print('this is process {}'.format(os.getpid())) def get_pool(n=5): p = Pool(n) # 设置进程池的大小 for i in range(10): p.apply_async(test) p.close() # 关闭进程池 p.join() if __name__ == '__main__': get_pool() print('ths process is ended')

分析:

如上,进程池Pool被创建出来后,即使实际需要创建的进程数远远大于进程池的最大上限,p1.apply_async(test)代码依旧会不停的执行,并不会停下等待;相当于向进程池提交了10个请求,会被放到一个队列中;

当执行完p1 = Pool(5)这条代码后,5条进程已经被创建出来了,只是还没有为他们各自分配任务,也就是说,无论有多少任务,实际的进程数只有5条,计算机每次最多5条进程并行。

当Pool中有进程任务执行完毕后,这条进程资源会被释放,pool会按先进先出的原则取出一个新的请求给空闲的进程继续执行;

当Pool所有的进程任务完成后,会产生5个僵尸进程,如果主线程不结束,系统不会自动回收资源,需要调用join函数去回收。

join函数是主进程等待子进程结束回收系统资源的,如果没有join,主程序退出后不管子进程有没有结束都会被强制杀死;

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpwwxz.html