多線程 進(jìn)程 協(xié)程
01 threading實(shí)現(xiàn)多線程
導(dǎo)入threading模塊
import threading-
創(chuàng)建對(duì)象
def sing(): for i in range(5): print("------Singing-----") time.sleep(1) ts = threading.Thread(target=sing)
注意 target參數(shù)只寫函數(shù)名隐岛,不能加括號(hào)猫妙,此時(shí)只創(chuàng)建了對(duì)象,沒有創(chuàng)建線程
-
控制子線程
ts.start() # 啟動(dòng)子線程 ts.join([time]) # 等待子線程運(yùn)行完成 ts.isAlive() # 返回子線程是否是存活的 ts.getName() # 返回子線程名 ts.setName() # 設(shè)置子線程名
調(diào)用start之后才創(chuàng)建了子線程聚凹,子線程從start開始執(zhí)行割坠,目標(biāo)函數(shù)結(jié)束后子線程運(yùn)行結(jié)束
-
運(yùn)行多個(gè)子線程
while True: length=len(threading.enumerate()) # print("\n當(dāng)前運(yùn)行的進(jìn)程數(shù):%d\n"%length) time.sleep(2) if length <= 1: print("\n所有子線程已運(yùn)行完成!6恃馈彼哼!\n") break
len(threading.enumerate())表示當(dāng)前運(yùn)行的線程數(shù),包括一個(gè)主線程
-
通過重載使用多線程
import threading import time class MyThread(threading.Thread): def run(self): for i in range(3): time.sleep(1) print("-----%d-----"%i) self.relax() def relax(self): print('-----relax-----\n') if __name__=='__main__': t=MyThread() t.start()
調(diào)用start時(shí)會(huì)自動(dòng)調(diào)用類中的run湘今,因此在類中必須定義run
-
互斥鎖
- 創(chuàng)建鎖(默認(rèn)是不加鎖的) mutex=threading.Lock()
- 上鎖 mutex.acquire()
- 解鎖 mutex.release()
- 判斷是否上鎖 mutex.locker()
02 multiprocessing實(shí)現(xiàn)多進(jìn)程
進(jìn)程與線程的區(qū)別:
- 進(jìn)程是資源分配的單位敢朱,線程是資源調(diào)度的單位
- 進(jìn)程需要的資源多 線程需要的資源少
- 進(jìn)程如同一條流水線 線程如同流水線上的工人
導(dǎo)入模塊
import multiprocessing-
創(chuàng)建對(duì)象
import time import multiprocessing def sing(): for i in range(5): print("------Singing-----") time.sleep(1) def dance(): for i in range(5): print("------Dancing-----") time.sleep(1) def main(): ts=multiprocessing.Process(target=sing) td=multiprocessing.Process(target=dance) ts.start() td.start() if __name__=='__main__': main()
- 調(diào)用start后才創(chuàng)建了子進(jìn)程,子進(jìn)程從start開始執(zhí)行摩瞎,子線程函數(shù)結(jié)束后子進(jìn)程運(yùn)行結(jié)束
- 子進(jìn)程會(huì)將主進(jìn)程的內(nèi)存復(fù)制拴签,復(fù)制變量的值。 代碼是共享的旗们,不復(fù)制 復(fù)制的越少越好蚓哩,能共享就共享
-
queue實(shí)現(xiàn)進(jìn)程間通信
import multiprocessing # 模擬下載數(shù)據(jù) def download_data(q): data=[1,2,3,4,5] for temp in data: q.put(temp) print('所有數(shù)據(jù)已經(jīng)存入!') # 模擬處理數(shù)據(jù) def data_process(q): get_data=list() while (q.empty()==False): data=q.get() get_data.append(data) print(get_data) def main(): #創(chuàng)建一個(gè)隊(duì)列 q=multiprocessing.Queue() p1=multiprocessing.Process(target=download_data,args=(q,)) p2=multiprocessing.Process(target=data_process,args=(q,)) p1.start() p2.start() if __name__=='__main__': main()
1. queue在內(nèi)存中開辟空間上渴,儲(chǔ)存用于通信的數(shù)據(jù)
queue只能用于同一個(gè)電腦的同一個(gè)程序
不指定隊(duì)列大小時(shí)岸梨,根據(jù)內(nèi)存自動(dòng)確定大小
創(chuàng)建進(jìn)程傳遞參數(shù)時(shí)喜颁,要注意傳遞的是一個(gè)元組,要加逗號(hào)
-
進(jìn)程池
在任務(wù)數(shù)不確定時(shí)盛嘿,往往使用進(jìn)程池import multiprocessing import os,time,random def job(msg): t_start=time.time() print('%s開始執(zhí)行洛巢,進(jìn)程號(hào)為:%d'%(msg,os.getpid())) time.sleep(random.random()*3) t_stop=time.time() t_cost=t_stop - t_start print('%s執(zhí)行執(zhí)行完畢括袒,耗時(shí)%0.2fs' % (msg, t_cost)) def main(): po=multiprocessing.Pool(3) # 設(shè)置進(jìn)程池容量為3 for i in range(10): po.apply_async(job,(i,)) # 兩個(gè)參數(shù)為要執(zhí)行的函數(shù)名和傳遞參數(shù)元組 print('----start----') po.close() # 關(guān)閉進(jìn)程池 po.join() # 等待池中所有進(jìn)程執(zhí)行結(jié)束 必須在close之后 print('----end----') if __name__=='__main__': main()
- 創(chuàng)建容納三個(gè)進(jìn)程的進(jìn)程池去執(zhí)行九個(gè)任務(wù)
- 進(jìn)程池使用queue通信時(shí)次兆,要使用manager下的queue
如q=multiprocessing.Manager().Queue()
03 gevent實(shí)現(xiàn)協(xié)程
-
gevent再遇到延時(shí)函數(shù)時(shí)會(huì)自動(dòng)切換協(xié)程,但要注意需要使用gevent中的延時(shí)函數(shù)锹锰,如將time.sleep()換成gevent.sleep()
如果想要使用原來的延時(shí)函數(shù)芥炭,可以添加語(yǔ)句:gevent.monkey.patch_all()
-
啟動(dòng)多個(gè)協(xié)程的方法
gevent.joinall( [ gevent.spawn(f1,5), gevent.spawn(f2,5), gevent.spawn(f3,5) # 設(shè)置目標(biāo)函數(shù)并傳遞參數(shù) ] )
協(xié)程傳遞參數(shù)使用的不是元組
-
代碼示例
from gevent import monkey gevent.monkey.patch_all() def f1(n): for i in range(n): print('f1:',i) time.sleep(1) def f2(n): for i in range(n): print('f2:',i) time.sleep(1) def f3(n): for i in range(n): print('f3:',i) time.sleep(1) gevent.joinall( [ gevent.spawn(f1,5), gevent.spawn(f2,5), gevent.spawn(f3,5) ] )