Python并发编程之进程
2018-04-01 17:22
661 查看
一、理论概念
1、定义
进程(Process也可以称为重量级进程)是程序的一次执行。在每个进程中都有自己的地址空间、内存、数据栈以及记录运行的辅助数据,它是系统进行资源分配和调度的一个独立单位。2、并行和并发
并行:并行是指多个任务同一时间执行;并发:是指在资源有限的情况下,两个任务相互交替着使用资源;
#!/usr/bin/envpython #-*-coding:utf-8-*- #Author:caoyf frommultiprocessingimportProcess,Pipe,Manager,Lock importtime importrandom #管道进程之间创建的一条管道,默认是全双工模式,两头都可以进和出, #注意必须在产生Process对象之前产生管道 #如果在Pipe括号里面填写False后就变成了单双工, #左边的只能收,右边的只能发,recv(接收),send(发送) #如果没有消息可以接收,recv会一直阻塞,如果连接的另外一段关闭后, #recv会抛出EOFError错误 #close关闭连接 #下面的实例是在Pipe的括号里填写和不填写False的区别 #frommultiprocessingimportProcess,Pipe #deffunc(pro): #pro.send('hello') #pro.close() # #if__name__=='__main__': #con,pro=Pipe(False) #p=Process(target=func,args=(pro,)) #p.start() #print(con.recv()) #p.join() #模拟recv阻塞情况 #deffunc(con,pro): #con.close() #while1: #try: #print(pro.recv()) #exceptEOFError: #pro.close() #break # # #if__name__=='__main__': #con,pro=Pipe() #p=Process(target=func,args=(con,pro,)) #p.start() #pro.close() #con.send('aaaaa') #con.close() #p.join() #利用管道实现生产者和消费者 #defsc(con,pro,name,food): #con.close() #foriinrange(5): #time.sleep(random.random()) #f='%s生产了%s%s'%(name,food,i) #print(f) #pro.send(f) #defxf(con,pro,name): #pro.close() #while1: #try: #baozi=con.recv() #print('%s消费了%s'%(name,baozi)) #exceptEOFError: #break #if__name__=='__main__': #con,pro=Pipe() #p1=Process(target=sc,args=(con,pro,'caoyf','包子')) #c1=Process(target=xf,args=(con,pro,'zhoaf')) #p1.start() #c1.start() #con.close() #pro.close() #p1.join()
管道
数据共享:
队列和管道只是实现了数据的传递,还没有实现数据的共享,如实现数据共享,就要用到Managers(注:进程间通信应该尽量避免使用共享数据的方式)frommultiprocessingimportProcess,Manager
importos
deff(dict1,list1):
dict1[os.getpid()]=os.getpid()#往字典里放当前PID
list1.append(os.getpid())#往列表里放当前PID
print(list1)
if__name__=="__main__":
withManager()asmanager:
d=manager.dict()#生成一个字典,可在多个进程间共享和传递
l=manager.list(range(5))#生成一个列表,可在多个进程间共享和传递
p_list=[]
foriinrange(10):
p=Process(target=f,args=(d,l))
p.start()
p_list.append(p)#存进程列表
forresinp_list:
res.join()
print('\n%s'%d)#若要保证数据安全,需要加锁lock=Lock()
进程池
对于需要使用几个甚至十几个进程时,我们使用Process还是比较方便的,但是如果要成百上千个进程,用Process显然太笨了,multiprocessing提供了Pool类,即现在要讲的进程池,能够将众多进程放在一起,设置一个运行进程上限,每次只运行设置的进程数,等有进程结束,再添加新的进程Pool(processes=num):设置运行进程数,当一个进程运行完,会添加新的进程进去
apply_async:异步,串行
apply:同步,并行
close():关闭pool,不能再添加新的任务
importos
importtime
importrandom
frommultiprocessingimportPool
frommultiprocessingimportProcess
deffunc(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)
start=time.time()
l=[]
foriinrange(1000):
p=Process(target=func,args=(i,))#创建了一百个进程
p.start()
l.append(p)
[i.join()foriinl]
print(time.time()-start)
回调函数:
importos
importtime
frommultiprocessingimportPool
#参数概念回调函数
deffunc(i):#多进程中的io多,分出去一部分
print('子进程%s:%s'%(i,os.getpid()))
returni*'*'
defcall(arg):#回调函数是在主进程中完成的,不能传参数,只能接受多进程中函数的返回值
print('回调:',os.getpid())
print(arg)
if__name__=='__main__':
print('主进程',os.getpid())
p=Pool(5)
foriinrange(10):
p.apply_async(func,args=(i,),callback=call)#callback回调函数:主进程执行参数是子进程执行的函数的返回值
p.close()
p.join()
相关文章推荐
- Python并发编程之进程
- python3全栈开发-并发编程的多进程理论
- Python并发编程之进程
- python并发编程之多进程理论(day9)
- python_fullstack基础(十八)-并发编程-进程
- Python并发编程之进程
- Python并发编程-进程
- python3全栈开发-并发编程,多进程的基本操作
- 理论讲解python多进程并发编程
- Python并发编程之进程
- python并发编程之多进程1-----------互斥锁与进程间的通信
- Python3 与 C# 并发编程之~ 进程篇
- python多进程并发编程
- 理解Python并发编程一篇就够了 | 进程篇
- Python并发编程__多进程
- Python并发编程之进程
- Python3 与 C# 并发编程之~ 进程篇
- Python并发编程之进程
- Python并发编程之进程
- 理解python并发编程-进程篇