管道:
conn1,conn2 = Pipe()
conn1.recv() # recv() 不需要加内容长度(整数)
conn1.send() # send() 不需要编码
数据接收一次就没有了
def chi(n):
print("我是子进程")
from_conn1 = n.recv()
print(from_conn1)
if __name__ == '__main__':
conn1,conn2 = Pipe()
p = Process(target=chi,args=(conn2,))
p.start()
conn1.send("儿子,干哈呢?")
print("父进程结束")
事件:
e = Event() #初识状态是false
e.wait() 当事件对象e的状态为false的时候,在wait的地方会阻塞程序,当对象状态为true的时候,直接在这个wait地方继续往下执行
e.set() 将事件对象的状态改为true,
e.is_set() 查看状态
e.clear() 将事件对象的状态改为false
信号量:
s = semphore(4),内部维护了一个计数器,acquire-1,release+1,为0的时候,其他的进程都要在acquire之前等待
只有这一种方式来锁
s.acquire()
需要锁住的代码
s.release()
import time
from multiprocessing import Process,Semaphore
def func1(n,m):
n.acquire()
print(f"{m}号女技师为您服务")
time.sleep(1)
n.release()
if __name__ == '__main__':
s = Semaphore(3)
for i in range(10):
p = Process(target=func1,args=(s,i+1,))
p.start()
进程池: 进程的创建和销毁是很有消耗的,影响代码执行效率
map:异步提交任务,并且传参需要可迭代类型的数据,自带close和join功能
测试多进程和进程池的效率对比:
import time
from multiprocessing import Process,Pool
def f1(m):
for i in range(5):
m += i
if __name__ == '__main__':
# 进程池设置三个进程
p1 = Pool(3)
# 创建进程时得到时间戳
p1_go_time = time.time()
# 参数1放进程的逻辑,参数2放可迭代对象.map是异步提交任务,但自带close和join
p1.map(f1,range(100))
# 所有进程结束后得到一个时间戳
p1_end_time = time.time()
p1_time = p1_end_time - p1_go_time
p2_lis = []
# 创建进程时得到时间戳
p2_go_time = time.time()
for i in range(100):
# 创建进程对象,把循环的内容当做参数,传给函数
p2 = Process(target=f1,args=(i,))
p2.start()
# 把进程对象都添加到列表中,方便让对象都join.
p2_lis.append(p2)
for i in p2_lis:
#把每个创建的进程对象都join,进程最慢的执行完之后,继续向下执行
#假如不加join的话,就是for循环创建完所有进程之后,直接向后执行,而子进程并没有执行完.
i.join()
# 所有多进程结束后得到一个时间戳
p2_end_time = time.time()
p2_time = p2_end_time - p2_go_time
print("进程池耗时:",p1_time)
print("多进程耗时:", p2_time)
res = apply( f1,args=(i,) ) #同步执行任务,必须等任务执行结束才能给进程池提交下一个任务,可以直接拿到返回结果res
import time
from multiprocessing import Process,Pool
def f1(n):
time.sleep(1)
# print(n)
return n*n
if __name__ == '__main__':
pool = Pool(4)
for i in range(10):
print('xxxxxx')
res = pool.apply(f1,args=(i,))
print(res)
res_obj = apply_async( f1,args=(i,) ) #异步提交任务,可以直接拿到结果对象,从结果对象里面拿结果,要用get方法,get方法会阻塞程序,没有拿到结果会一直等待
close : 锁住进程池,防止有其他的新的任务在提交给进程池
join : 等待着进程池将自己里面的任务都执行完
get : 拿到函数在进程执行的结果,没有拿到结果会一直等待,get方法会阻塞程序
import time
from multiprocessing import Process, Pool
def f1(n):
time.sleep(2)
print(n)
return n * n
if __name__ == '__main__':
pool = Pool(4)
res_list = []
for i in range(10):
print('xxxx')
# 异步给进程池提交任务
res = pool.apply_async(f1, args=(i,))
res_list.append(res)
print('等待所有进程执行完')
pool.close() #锁住进程池,意思就是不让其他的程序再往这个进程池里面提交任务了
pool.join() #等进程执行完之后,才继续向下执行
print('所有进程执行结束')
time.sleep(2)
# 打印结果,如果异步提交之后的结果对象
for i in res_list:
print(i.get())
print("主程序结束")
回调函数:
apply_async(f1,args=(i,),callback=function) #将前面f1这个任务的返回结果作为参数传给callback指定的那个function函数