一、为什么要有进程池

  首先,创建进程需要消耗时间,销毁进程也需要时间。其次,即使开启了成千上万的进程,操作系统也不能让它们同时执行,这样反而会影响程序的效率。因此我们不能无限制的根据任务开启或者结束进程。

进程池:定义了一个池子,在里面放上固定数量的进程,有需求来了,就拿这个池中的一个进程来处理任务,等到处理完毕,进程并不关闭,而是将进程再放回进程池中继续等待认为。如果有许多任务需要执行,池中的进程数量不够,任务就要等待之前的进程执行任务完毕归来,拿到空闲进程才能继续执行。

总结:也就是说,池中进程的数量是固定的,那么同一时间最多有固定数量的进程再运行。这样 不会增加操作系统的调度难度,还节省了开闭进程的时间,也一定程度上能够实现并发效果。

二、进程池和多进程效率对比

import os
import time
import random
from multiprocessing import Pool
from multiprocessing import Process
def func(i):
i += 1
if __name__ == '__main__':
p = Pool(5) # 创建了5个进程
start = time.time()
p.map(func,range(1000))
p.close() # 是不允许再向进程池中添加任务
p.join()
print(time.time() - start) # 0.35544490814208984
start = time.time()
l = []
for i in range(1000):
p = Process(target=func,args=(i,)) # 创建了一百个进程
p.start()
l.append(p)
[i.join() for i in l]
print(time.time() - start) # 101.00088691711426
import os,time
from multiprocessing import Pool def work(n):
print('%s run' %os.getpid())
time.sleep(3)
return n**2 if __name__ == '__main__':
p=Pool(3) #进程池中从无到有创建三个进程,以后一直是这三个进程在执行任务
res_l=[]
for i in range(10):
res=p.apply(work,args=(i,)) # 同步调用,直到本次任务执行完毕拿到res,等待任务work执行的过程中可能有阻塞也可能没有阻塞
# 但不管该任务是否存在阻塞,同步调用都会在原地等着
print(res_l)

进程池的同步调用

import os
import time
import random
from multiprocessing import Pool def work(n):
print('%s run' %os.getpid())
time.sleep(random.random())
return n**2 if __name__ == '__main__':
p=Pool(3) #进程池中从无到有创建三个进程,以后一直是这三个进程在执行任务
res_l=[]
for i in range(10):
res=p.apply_async(work,args=(i,)) # 异步运行,根据进程池中有的进程数,每次最多3个子进程在异步执行
# 返回结果之后,将结果放入列表,归还进程,之后再执行新的任务
# 需要注意的是,进程池中的三个进程不会同时开启或者同时结束
# 而是执行完一个就释放一个进程,这个进程就去接收新的任务。
res_l.append(res) # 异步apply_async用法:如果使用异步提交的任务,主进程需要使用jion,等待进程池内任务都处理完,然后可以用get收集结果
# 否则,主进程结束,进程池可能还没来得及执行,也就跟着一起结束了
p.close()
p.join()
for res in res_l:
print(res.get()) #使用get来获取apply_aync的结果,如果是apply,则没有get方法,因为apply是同步执行,立刻获取结果,也根本无需get

进程池的异步调用

通过进程池利用socket实现并发聊天

#Pool内的进程数默认是cpu核数,假设为4(查看方法os.cpu_count())
#开启6个客户端,会发现2个客户端处于等待状态
#在每个进程内查看pid,会发现pid使用为4个,即多个客户端公用4个进程
from socket import *
from multiprocessing import Pool
import os server=socket(AF_INET,SOCK_STREAM)
server.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
server.bind(('127.0.0.1',8080))
server.listen(5) def talk(conn):
print('进程pid: %s' %os.getpid())
while True:
try:
msg=conn.recv(1024)
if not msg:break
conn.send(msg.upper())
except Exception:
break if __name__ == '__main__':
p=Pool(4)
while True:
conn,*_=server.accept()
p.apply_async(talk,args=(conn,))
# p.apply(talk,args=(conn,client_addr)) #同步的话,则同一时间只有一个客户端能访问

server端

from socket import *
client=socket(AF_INET,SOCK_STREAM)
client.connect(('127.0.0.1',8080))
while True:
msg=input('>>: ').strip()
if not msg:continue
client.send(msg.encode('utf-8'))
msg=client.recv(1024)
print(msg.decode('utf-8'))

client端

import os
import time
from multiprocessing import Pool
# 参数 概念 回调函数
def func(i): # 多进程中的io多,
print('子进程%s:%s'%(i,os.getpid()))
return i*'*' def call(arg): # 回调函数是在主进程中完成的,不能传参数,只能接受多进程中函数的返回值
print('回调 :',os.getpid())
print(arg) if __name__ == '__main__':
print('---->',os.getpid())
p = Pool(5)
for i in range(10):
p.apply_async(func,args=(i,),callback=call)
p.close()
p.join()

回调函数

如果在主进程中等待进程池中所有任务都执行完毕后,再统一处理结果,则无需回调函数。

from multiprocessing import Pool
import time,random,os def work(n):
time.sleep(1)
return n**2
if __name__ == '__main__':
p=Pool() res_l=[]
for i in range(10):
res=p.apply_async(work,args=(i,))
res_l.append(res) p.close()
p.join() #等待进程池中所有进程执行完毕 nums=[]
for res in res_l:
nums.append(res.get()) #拿到所有结果
print(nums) #主进程拿到所有的处理结果,可以在主进程中进行统一进行处理

无需回调函数

进程池和multiprocess.Pool模块的更多相关文章

  1. 进程同步控制(锁,信号量,事件), 进程通讯(队列和管道,生产者消费者模型) 数据共享(进程池和mutiprocess.Pool模块)

    参考博客 https://www.cnblogs.com/xiao987334176/p/9025072.html#autoid-1-1-0 进程同步(multiprocess.Lock.Semaph ...

  2. 进程池 和 multiprocessing.Pool模块

    进程池的概念 在程序实际处理问题过程中,忙时会有成千上万的任务需要被执行,闲时可能只有零星任务.那么在成千上万个任务需要被执行的时候,我们就需要去创建成千上万个进程么?首先,创建进程需要消耗时间,销毁 ...

  3. Python之进程 3 - 进程池和multiprocess.Poll

    一.为什么要有进程池? 在程序实际处理问题过程中,忙时会有成千上万的任务需要被执行,闲时可能只有零星任务.那么在成千上万个任务需要被执行的时候,我们就需要去创建成千上万个进程么?首先,创建进程需要消耗 ...

  4. python 进程池(multiprocessing.Pool)和线程池(threadpool.ThreadPool)的区别与实例

    一般我们是通过动态创建子进程(或子线程)来实现并发服务器的,但是会存在这样一些缺点: 1.动态创建进程(或线程)比较耗费时间,这将导致较慢的服务器响应.  2.动态创建的子进程通常只用来为一个客户服务 ...

  5. python全栈开发 * 进程池,线程理论 ,threading模块 * 180727

    一.进程池 (同步 异步 返回值) 缺点: 开启进程慢 几个CPU就能同时运行几个程序 进程的个数不是无线开启的 应用: 100个任务 进程池 如果必须用多个进程 且是高计算型 没有IO型的程序 希望 ...

  6. python进程池:multiprocessing.pool

    本文转至http://www.cnblogs.com/kaituorensheng/p/4465768.html,在其基础上进行了一些小小改动. 在利用Python进行系统管理的时候,特别是同时操作多 ...

  7. python multiprocess pool模块报错pickling error

    问题 之前在调用class内的函数用multiprocessing模块的pool函数进行多线程处理的时候报了以下下错误信息: PicklingError: Can't pickle <type ...

  8. 进程池的同步方法 pool.apply

    from multiprocessing import Pool,Process def f1(n): print(n) return n*n if __name__ == "__main_ ...

  9. python 全栈开发,Day40(进程间通信(队列和管道),进程间的数据共享Manager,进程池Pool)

    昨日内容回顾 进程 multiprocess Process —— 进程 在python中创建一个进程的模块 start daemon 守护进程 join 等待子进程执行结束 锁 Lock acqui ...

随机推荐

  1. Cocos2d-x视频教程

    目录 1. 我的技术专栏 2. 相关推荐 3. 下载链接 4. cocos2d-xx Lua+JS+C++教学视频 5. 杨丰盛Cocos2D-X游戏课程 6. [Cocos2d-x]塔防游戏开发实战 ...

  2. 21eval 函数

    eval() 函数十分强大 ---- 将字符串 当成 有效的表达式 来求职 并 返回计算结果 # 基本的数学计算 # 字符串重复 print(eval("'*' * 5")) # ...

  3. linux系统升级openssh

    一.升级前准备工作 安装openssh过程需gcc,zlib-devel,openssl-devel,等编译环境,如果通过rpm包来安装,需要解决各种依赖包,故配置本地yum源解决依赖问题. 1. 配 ...

  4. python3-返回函数

    函数作为返回值 高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回. 我们来实现一个可变参数的求和.通常情况下,求和的函数是这样定义的: def calc_sum(*args): ax = ...

  5. python字符串前面的u,还有r

    以u或U开头的字符串表示unicode字符串 如果你想要用非英语写文本,那么你需要有一个支持Unicode的编辑器.(了解一下unicode和ascll码还有utf-8) u'你好'        # ...

  6. python开发之virtualenv与virtualenvwrapper

    在使用 Python 开发的过程中,工程一多,难免会碰到不同的工程依赖不同版本的库的问题: 亦或者是在开发过程中不想让物理环境里充斥各种各样的库,引发未来的依赖灾难. 此时,我们需要对于不同的工程使用 ...

  7. linux运维、架构之路-linux文件权限

    一. R W X对应的数字及计算的方法 1.linux普通文件权限总结 ①r可读:表示具有读取.浏览文件内容(block)的权限 ②w可写:表示具有新增.修改文件内容的权限删除文件(修改文件名.)或创 ...

  8. 多个webView嵌套在UIScrollView里面内存优化

    之前一直纠结在使用UIWebView上,发现加载6个UIWebView占用了290M左右内存,切换时还会增加.后来看到一篇文章:http://blog.csdn.net/kongu/article/d ...

  9. spring boot 简介(基于SSM框架的一个升级版本吧)

    Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置.通过 ...

  10. HTML基础入门学习

    上一篇给大家介绍了学习HTML的准备工作,本文开始带大家步入HTML的学习 一.HTML基础 网页的组成: HTML:页面构成 css:页面样式表现 JavaScript:交互行为 HTML简介: H ...