笔记:
昨日内容回顾:
进程同步:
锁 : 将异步变为同步,保证数据安全,
信号量 : 可以规定同时进入锁内执行的进程数量
事件 :
进程通信:IPC
队列 :
生产者消费者模型 : 解耦,缓冲,解决双方效率差异问题
JoinableQueue :
今日内容:
管道 数据共享 进程池 线程
管道:
管道的数据不安全:
Manager数据共享,也是数据不安全的
进程池( 重点 )
明日预习内容
https://www.cnblogs.com/clschao/articles/9684694.html
明天默写内容:
什么是进程池
进程池有哪些方法
简述回调函数
作业:
1 进程池版的socket并发聊天
2 爬虫:最少爬4个网页,并发,拿到返回数据之后,直接给回调函数,回调函数做数据清洗的(re)找网页中一些内容,(在想搞的,可以将数据清洗的操作搞多进程)
apply_async的其他方法.py
import time
from multiprocessing import Process,Pool
def fun(i):
time.sleep(1)
print(i)
return i**2
if __name__ == '__main__':
p = Pool(4)
res_list = []
for i in range(10):
res = p.apply_async(fun,args=(i,)) #同步执行的方法,他会等待你的任务的返回结果,
# print('结果:',res.get())
res_list.append(res)
# print('iiiiiiiiiiiii')
p.close() # 不是关闭进程池,而是不允许再有其他任务来使用进程池
p.join() # 这是感知进程池中任务的方法,进程池中所有的进程随着主进程的结束而结束了,等待进程池的任务全部执行完
# time.sleep(2)
#循环打印结果
# print('>>>>',res_list)
for e_res in res_list:
print('结果:',e_res.get())
print('主进程结束')
数据共享.py
from multiprocessing import Process,Manager
def func(m_dic):
m_dic['name'] = '刘伟卖药的'
if __name__ == '__main__':
m = Manager()
m_dic = m.dict({'name':'伟哥'})
print('主进程', m_dic)
p = Process(target=func,args=(m_dic,))
p.start()
p.join()
print('主进程',m_dic)
数据共享manmger不安全.py
from multiprocessing import Process,Manager,Lock
def func(m_dic,ml):
#不加锁的情况会出现数据错乱
# m_dic['count'] -= 1
#加锁,这是另外一种加锁形式
with ml:
m_dic['count'] -= 1
#等同
# ml.acquire()
# m_dic['count'] -= 1
# ml.release()
if __name__ == '__main__':
m = Manager()
ml = Lock()
m_dic = m.dict({'count':100})
# print('主进程', m_dic)
p_list = []
#开启20个进程来对共享数据进行修改
for i in range(20):
p1 = Process(target=func,args=(m_dic,ml,))
p1.start()
p_list.append(p1)
[ppp.join() for ppp in p_list]
print('主进程',m_dic)
管道.py
from multiprocessing import Process,Pipe
# conn1, conn2 = Pipe()
# conn1.send('你好')
# print('>>>>>>>>>')
# msg = conn2.recv()
# print(msg)
# def func1(conn2):
# try:
# msg = conn2.recv()
# print('>>>',msg)
# #如果管道一端关闭了,那么另外一端在接收消息的时候会报错
# msg2 = conn2.recv() #EOFError
# except EOFError:
# print('对方管道一端已经关闭')
# conn2.close()
#管道错误模拟
# def func1(conn1,conn2):
# try:
# msg = conn2.recv()
# print('>>>',msg)
# #如果管道一端关闭了,那么另外一端在接收消息的时候会报错
# msg2 = conn2.recv() #EOFError
# except EOFError:
# print('对方管道一端已经关闭')
# conn2.close()
#
# if __name__ == '__main__':
# conn1, conn2 = Pipe()
# p = Process(target=func1,args=(conn1,conn2,))
# p.start()
# conn1.send('小鬼!')
# conn1.close()
# # conn1.recv() #OSError: handle is closed
def func1(conn1,conn2):
msg = conn2.recv() #阻塞
if __name__ == '__main__':
conn1, conn2 = Pipe()
p = Process(target=func1,args=(conn1,conn2,))
p.start()
# conn1.send('小鬼!')
# conn1.close()
# conn1.recv() #OSError: handle is closed
线程初识.py
from threading import Thread
import time
# def fun(n):
# time.sleep(3)
# print(n)
#
# if __name__ == '__main__':
# t = Thread(target=fun,args=(1,))
# t.start()
# t.join()
# print('主线程')
#第二种创建方法
# class MyThread(Thread):
# def __init__(self,n):
# super().__init__()
# self.n = n
# def run(self):
# # print('换汤不换药')
# print('self.n>>>>',self.n)
# if __name__ == '__main__':
# t = MyThread('nihao')
# t.start()
# t.join()
# print('主线程结束')
进程池.py
import time
from multiprocessing import Process,Pool
def func(n):
for i in range(5):
n = n + i
print(n)
if __name__ == '__main__':
#验证一下传参
pool_start_time = time.time()
pool = Pool(4)
pool.map(func,range(100)) #map自带join功能,异步执行任务,参数是可迭代的
pool_end_time = time.time()
pool_dif_time = pool_end_time - pool_start_time
p_s_time = time.time()
p_list = []
for i in range(200):
p1 = Process(target=func,args=(i,))
p1.start()
p_list.append(p1)
[p.join() for p in p_list]
p_e_time = time.time()
p_dif_time = p_e_time - p_s_time
print('进程池的执行时间',pool_dif_time)
print('多进程的执行时间',p_dif_time)
进程池map传参.py
import time
from multiprocessing import Process,Pool
def func(n):
print(n)
if __name__ == '__main__':
pool = Pool(4)
# pool.map(func,range(100)) #参数是可迭代的
pool.map(func,['sb',(1,2)]) #参数是可迭代的
进程池的同步方法.py
import time
from multiprocessing import Process,Pool
def fun(i):
time.sleep(0.5)
# print(i)
return i**2
if __name__ == '__main__':
p = Pool(4)
for i in range(10):
res = p.apply(fun,args=(i,)) #同步执行的方法,他会等待你的任务的返回结果,
print(res)
进程池的回调函数.py
import os
from multiprocessing import Pool
def func1(n):
print('func1>>',os.getpid())
# print('func1')
return n*n
def func2(nn):
print('func2>>',os.getpid())
# print('func2')
print(nn)
# import time
# time.sleep(0.5)
if __name__ == '__main__':
print('主进程:',os.getpid())
p = Pool(4)
p.apply_async(func1,args=(10,),callback=func2)
p.close()
p.join()
进程池的异步方法.py
import time
from multiprocessing import Process,Pool
def fun(i):
time.sleep(0.5)
print(i)
return i**2
if __name__ == '__main__':
p = Pool(4)
res_list = []
for i in range(10):
res = p.apply_async(fun,args=(i,)) #同步执行的方法,他会等待你的任务的返回结果,
# print(res.get())
res_list.append(res)
# print('>>>>>',res)
# for i in res_list:
# print(i.get())