进程池的同步,如下程序:

from multiprocessing import Pool
import time
import os def func(n):
print('start 进程 %s'%n, os.getpid())
time.sleep(1)
print('end 进程 %s'%n, os.getpid()) if __name__ == "__main__":
pool = Pool() # 如果进程池不加数字,默认值为往前CPU的数量一样
for i in range(10):
pool.apply(func, args=(i,))

查看结果:

start 进程 0 21896
end 进程 0 21896
start 进程 1 27040
end 进程 1 27040
start 进程 2 23408
end 进程 2 23408
start 进程 3 29704
end 进程 3 29704
start 进程 4 31384
end 进程 4 31384
start 进程 5 2140
end 进程 5 2140
start 进程 6 25780
end 进程 6 25780
start 进程 7 29488
end 进程 7 29488
start 进程 8 21896
end 进程 8 21896
start 进程 9 27040
end 进程 9 27040

可以发现,变成了进程变成了同步得了,运行特别慢。

apply方法的作用就是将进程池的进程变成同步的。

将进程池变成异步的,使用apply_async就可以了,如下:

from multiprocessing import Pool
import time
import os def func(n):
print('start 进程 %s'%n, os.getpid())
time.sleep(1)
print('end 进程 %s'%n, os.getpid()) if __name__ == "__main__":
pool = Pool()
for i in range(10):
pool.apply_async(func, args=(i,))

但是发现结果什么都没有,因为主进程没有等子进程的结束就执行完了。

如下优化,使用join就行了:

from multiprocessing import Pool
import time
import os def func(n):
print('start 进程 %s'%n, os.getpid())
time.sleep(1)
print('end 进程 %s'%n, os.getpid()) if __name__ == "__main__":
pool = Pool()
for i in range(10):
pool.apply_async(func, args=(i,))
pool.close() # close()保证的是没有新的任务进入进程池
pool.join() # 这里的join检测的是子进程里面的任务结束,而不是子进程的结束,因为进程池里面的进程不会结束,永远活着,被用完之后会被还到进程池里面。

看结果:

start 进程 0 22364
start 进程 1 25820
start 进程 2 27688
start 进程 3 26840
start 进程 4 31100
start 进程 5 27032
start 进程 6 21452
start 进程 7 25592
end 进程 0 22364
start 进程 8 22364
end 进程 1 25820
start 进程 9 25820
end 进程 2 27688
end 进程 3 26840
end 进程 4 31100
end 进程 5 27032
end 进程 6 21452
end 进程 7 25592
end 进程 8 22364
end 进程 9 25820

值得注意的是,不加pool.close(),直接加pool.join()是会报错的,因为进程池里面的进程用完之后不会结束,而是被还到进程池了,因此这里的join检测的是没有任务再进入进程池了,而不是检测子进程的结束。所以要保证没有任务进入进程池,进程池就不会接收到任务,所以pool.close()的作用就是结束进程池接收任务,就是我的任务执行完毕,且没有新的任务进来,这是就被join检测到了。

另一种问题如下:

from multiprocessing import Pool
import time def func(n):
time.sleep(0.5)
return n*n if __name__ == "__main__":
pool = Pool(5)
for i in range(10):
ret = pool.apply(func, args=(i,))
print(ret)

打印结果:

0
1
4
9
16
25
36
49
64
81 # 每隔0.5秒打印一个结果

看下一段代码,使用apply_async:

from multiprocessing import Pool
import time def func(n):
time.sleep(0.5)
return n*n if __name__ == "__main__":
pool = Pool(5)
for i in range(10):
ret = pool.apply_async(func, args=(i,))
print(ret)

看打印结果:

<multiprocessing.pool.ApplyResult object at 0x0000023993E70AC8>
<multiprocessing.pool.ApplyResult object at 0x0000023993E70B70>
<multiprocessing.pool.ApplyResult object at 0x0000023993E70CF8>
<multiprocessing.pool.ApplyResult object at 0x0000023993E70DA0>
<multiprocessing.pool.ApplyResult object at 0x0000023993E70E80>
<multiprocessing.pool.ApplyResult object at 0x0000023993E70F28>
<multiprocessing.pool.ApplyResult object at 0x0000023993E70FD0>
<multiprocessing.pool.ApplyResult object at 0x0000023993E810B8>
<multiprocessing.pool.ApplyResult object at 0x0000023993E81160>
<multiprocessing.pool.ApplyResult object at 0x0000023993E81208>

是一个个对象,并且是同时打印出来的。

优化如下,使用get()方法获取值:

from multiprocessing import Pool
import time def func(n):
time.sleep(0.5)
return n*n if __name__ == "__main__":
pool = Pool(5)
for i in range(10):
ret = pool.apply_async(func, args=(i,))
print(ret.get())

看打印结果:

0
1
4
9
16
25
36
49
64
81

值出来的,但是你会发现一个现象,值是每隔0.5秒一个一个出来的,不是异步吗???

这里要注意for循环将任务传入如进程池时,

    for i in range(10):
ret = pool.apply_async(func, args=(i,)) # for循环传入任务
print(ret.get())

执行到print(ret.get()),这里的get需要获取值,但是这是没有值,get就会让程序出现阻塞直到等到值,所以for循环的每一步都要等到值才会继续下一个for循环,就出现了不是异步的情况。

改进方法:

from multiprocessing import Pool
import time def func(n):
time.sleep(0.5)
return n*n if __name__ == "__main__":
pool = Pool(5)
l_list = []
for i in range(10):
ret = pool.apply_async(func, args=(i,))
l_list.append(ret)
for m in l_list:
print(m.get())

这时候你会发现五个五个的出现。

结束!

最新文章

  1. Cucumber(一): Preparation
  2. 获取img的真实宽高
  3. 【一套C语言控制台的输出框代码】
  4. DataTable转List&lt;dynamic&gt;
  5. 浅谈attr()和prop()
  6. 【leetcode】Next Permutation
  7. React的一个简单示例
  8. 举例详解CSS中的继承
  9. convertView的疑问(软件管理器)
  10. tomcat websocket 实现网页在线即时聊天
  11. nginx 安装和配置
  12. 我眼中的 Nginx(四):是什么让你的 Nginx 服务退出这么慢?
  13. 顶尖 API 文档管理工具 (Yapi)
  14. 缓存系列之五:通过codis3.2实现redis3.2.8集群的管理
  15. 微信小程序 条件渲染 wx:if
  16. Python reverse
  17. Kubernetes中的nodePort,targetPort,port的区别和意义(转)
  18. win10自带虚拟机Hyper V联网
  19. 关于“用VS2010的C++导入ADO导入不了,提示无法打开源文件msado15.tlh”的问题
  20. HDU-2680 Choose the best route 单向边+反向dijkstra

热门文章

  1. django之ORM补充
  2. JSOUP 请求JSON
  3. spring boot swagger-ui.html 404
  4. (20170207)开源第三方学习之JSONModel
  5. sort is deprecated, use sort_values(inplace=True) for INPLACE sorting
  6. [druid]大数据挑战——如何使用Druid实现数据聚合
  7. Redis 分布式锁的实现
  8. vs2013cs页面的代码太长,除了方法,没有折叠,如何处理
  9. 【转】Android系统开篇
  10. Git操作自动触发企业微信机器人webhook