Python的进程和线程是使用的操作系统的原生线程和进程,其是去调用操作系统的相应接口实现
进程:之间不可直接共享数据,是资源的集合,进程必须有一个线程
线程:基于进程,之间可直接共享数据,可执行,只有所有的线程执行完毕程序才会退出
守护线程:生命值依赖于创建它的主线程,主程序亡,不管守护进程执行到何步也必须立即亡
多线程:不适用与CPU操作任务大的(如计算等),较适合于IO操作任务大的(如文件读写等)
进程
简单的进程
在Windows上启动进程必须加入【if __name__=="__main__":】,而在linux上则可随意,进程的使用基本与线程相同
import multiprocessing time def run11(): print("----- 进程 ----") # win 进程启动,必须加入这句 if __name__==__main__: 启动进程 t1=multiprocessing.Process(target=run11,args=()) t1.start()
进程间传递数据之进程队列:
1 2 3 run11(qqlistx): 4 ****** 进入进程 ********) 5 设置进程数据 6 qqlistx.put(11111122 7 8 9 : 10 11 进程队列 12 qqlistx = multiprocessing.Queue() 13 14 启动进程,必须传递进程队列 15 t1=multiprocessing.Process(target=run11,1)">(qqlistx,)) 16 t1.start() 17 18 得到进程数据:",qqlistx.get())
进程间传递数据之管道:
run11(pp1): 5 6 发送数据 7 pp1.send(东小东 8 收到mian进程发来的数据:,pp1.recv()) 9 10 11 12 13 得到管道 得到两端,如同socket的服务器和客户端 15 任意一端都可以进行收发 16 pp1,pp2 = multiprocessing.Pipe() 启动进程,传递任意一端 19 t1=multiprocessing.Process(target=run11,1)">(pp1,1)">20 21 22 另一端接收数据 23 24 pp2.send(收到数据了东小东")
进程之数据共享:
两个进程进行数据共享,列表或者字典数据共享
run11(vv): 6 vv[dong"]=dongxiaodong" 7 vv.append("555") #列表 8 11 12 方法一 -------------: with multiprocessing.Manager() as mssaagex: dictx=mssaagex.dict() #得到字典参数 #listx=mssaagex.list() #得到列表参数 16 # 17 #启动进程,传递字典或者列表 t1=multiprocessing.Process(target=run11,args=(dictx,)) 19 t1.start() 20 21 #等待进程接收 t1.join() 24 #打印字典数据 25 print("得到进程数据:",dictx) 26 27 方法二 -------------------: 28 dictx=multiprocessing.Manager().dict() 得到字典参数 29 listx=multiprocessing.Manager().list() #得到列表参数 30 31 启动进程,传递字典或者列表 32 t2=multiprocessing.Process(target=run11,1)">(dictx,1)">33 t2.start() 34 35 等待进程接收 36 t2.join() 37 38 打印字典数据 394 vv.acquire() 上锁 5 6 vv.release() 解锁 12 lockx=multiprocessing.Lock() 得到进程锁 14 t2=multiprocessing.Process(target=run11,1)">(lockx,1)">15t2.start()
进程池:
确定进程的同时运行个数,更好的进行进程管理
2 time 3 4 5 time.sleep(1 6 回调函数 在主进程中运行 Cal(arg): 每个进程的回调函数13 14 15 16 poolx=multiprocessing.Pool(2) 得到进程池,最多同时执行2个进程 18 启动进程 19 for i in range(10): 20 poolx.apply_async(func=run11,args=(i,)) #并行 21 poolx.apply_async(func=run11,),callback=Cal) 并行并加入执行完毕的回调函数 22 poolx.apply(func=run11,)) #串行 23 24 等待并关闭进程 25 poolx.close() 26 poolx.join() ----- 完毕 -----")
协程:
单线程实现高并发
安装:pip3 install gevent
手动切换:
greenlet gfunx1(): ----gfunx1---) g2.switch() 手动切换到 gfunx2 中 gfunx2(): ---gfunx2----声明两个协程 g1=greenlet.greenlet(gfunx1) g2=greenlet.greenlet(gfunx2) g1.switch() 手动切换到 gfunx1 中
自动切换:
默认是先运行完gfunx1然后再运行gfunx2,但当遇到IO操作则会自动跳转到另一个协程工作,以此实现在协程中遇到IO就互相切换执行的效果
gevent gfunx1(): 4 ---- gfunx1 --- 5 gevent.sleep(3) 模拟 IO 操作为 3 秒,但使用time.sleep(x)则会进行阻塞 **** 三秒io操作结束 ****** gfunx2(): 9 ---- gfunx2 ----12 开启两个协程 gevent.joinall([ gevent.spawn(gfunx1),15 gevent.spawn(gfunx2),1)">16 ])
自动切换进阶:
将一系列阻塞操作让协程识别为IO操作
from gevent monkey 将所有的阻塞操作(如:网络,延时,文件等)都视为gevent可捕获的IO阻塞操作 根据库作者提示:此句最好放在其它库import之前,否则会出现警告 5 monkey.patch_all() 6 7 requests 12 res=requests.get(https://img2018.cnblogs.com/blog/1485202/201811/1485202-20181116215233782-319594948.png13 open(ww.jpgwb").write(res.content) 以二进制写文件 **** 网络操作结束 ******18 time.sleep(3) 延时操作也已视为IO阻塞 *** 延时操作结束 3s ***20 21 gfunx3(varx): ---- gfunx3 ----23 time.sleep(1*** 延时操作结束 1s ***25 27 开启三个协程 28 29 30 31 gevent.spawn(gfunx3,1)">33333") 传递参数 32 ])