您的位置:首页 > 编程语言 > Python开发

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()
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: