multiprocessing.Process,multiprocessing.Pool区别

1. 是否可以批量开启子进程

multiprocessing.Process 无法批量开启子进程

multiprocessing.Pool可以批量开启子进程

  1. p = Pool(2)
  2. p.map() /
  3. p.apply_sync()
  4. p.close()
  5. p.join()
  6. #或者用with方式
  7. with Pool( 2) as p:
  8. p.map() / p.apply_sync()

2. 进程间通信

multiprocessing.Process 可以直接用multiprocesssing.Queue等进行通信,可以参考下面的代码

  1. from multiprocessing import Process,Queue
  2. import os
  3. def run_proc(name,q):
  4. print( 'Run Child process %s (%s)' % (name, os.getpid()))
  5. q.put( 'value')
  6. def run_proce(name,q):
  7. print( 'Run Child process %s (%s)' % (name, os.getpid()))
  8. print(q.get())
  9. if __name__ == '__main__':
  10. print( 'Parent process %s.' % os.getpid())
  11. q = Queue()
  12. p = Process(target=run_proc,args=( 'test',q))
  13. p2 = Process(target=run_proce,args=( 'test2',q))
  14. print( 'Child Process will start')
  15. p.start()
  16. p.join()
  17. p2.start()
  18. p2.join()
  19. print( 'Child process end.')

multiprocessing.Pool不能直接用multiprocessing.Queue进行通信,只能通过共享内存,或者用multiprocessing.Manager()进行进程间通信。参考以下代码,代码一为使用multiprocessing.Queue进行通信,代码二是multiprocessing.Manager()进行进程间通信

代码一:

  1. from multiprocessing import Pool,Queue,Manager
  2. import os
  3. def run_proc(name,q):
  4. print( 'Run Child process %s (%s)' % (name, os.getpid()))
  5. q.put( 'value')
  6. if __name__ == '__main__':
  7. print( 'Parent process %s.' % os.getpid())
  8. q = Queue()
  9. p = Pool( 2)
  10. L = [ 1, 2]
  11. for l in L:
  12. p.apply_async(run_proc,args=(l,q))
  13. print( 'Child Process will start')
  14. p.close()
  15. p.join()
  16. print( 'Child process end.')
  17. print(q.get())

上面的代码执行后,控制台打印结果如下,并且程序一直未能结束。

  1. Parent process 4640.
  2. Child Process will start
  3. Child process end.

代码二:

  1. from multiprocessing import Pool,Queue,Manager
  2. import os
  3. def run_proc(name,q):
  4. print( 'Run Child process %s (%s)' % (name, os.getpid()))
  5. q.put( 'value')
  6. if __name__ == '__main__':
  7. print( 'Parent process %s.' % os.getpid())
  8. q = Manager().Queue()
  9. p = Pool( 2)
  10. L = [ 1, 2]
  11. for l in L:
  12. p.apply_async(run_proc,args=(l,q))
  13. print( 'Child Process will start')
  14. p.close()
  15. p.join()
  16. print( 'Child process end.')
  17. print(q.get())

代码二的执行结果如下:

  1. Parent process 4864.
  2. Child Process will start
  3. Run Child process 1 ( 6008)
  4. Run Child process 2 ( 5112)
  5. Child process end.
  6. value

Note:

1. multiprocess.Manager()只能在主进程中使用,因为multiprocess.Manager()初始化后会开启一个server process,而在子进程中因为默认的daemon为True,(即默认是守护进程,不允许创建子进程,并且父进程代码执行结束,子进程也会终止允许)。如果在子进程中使用multiprocess.Manager(),就会抛出异常:AssertionError:daemonic processes are not allowed to have children.

2. 因为在Linux或者Mac系统,multiprocessing.Pool默认开启子进程的方式是通过fork。也可以通过multiprocess.set_start_method()方法修改开启的方式为spawn/ forkserver。那么如果要调用该方法,那么 multiprocess.Manager()应该用在multiprocess.set_start_method()方法之后。否则,就会抛出异常:Runtimeerror: context has already been set

Ref:

廖雪峰-多进程

转自: Oops_newbie的博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值