1. 進(jìn)程
進(jìn)程:計(jì)算機(jī)中一個程序在一個數(shù)據(jù)集上一次動態(tài)執(zhí)行過程,主要包含三部分內(nèi)容
? 程序:描述進(jìn)程的功能以及處理流程
? 數(shù)據(jù)集:功能處理過程中需要的資源數(shù)據(jù)
? 進(jìn)程控制:嚴(yán)格控制進(jìn)程執(zhí)行過程中的各種狀態(tài)
通俗來說,一個進(jìn)程就是計(jì)算機(jī)上正在運(yùn)行的一個程序
2. 線程
計(jì)算機(jī)中程序運(yùn)行的實(shí)際執(zhí)行者就是線程,線程又稱為輕量級進(jìn)程,是一個CPU的執(zhí)行單 元,每個進(jìn)程至少會有一個主線程用于執(zhí)行程序
線程和進(jìn)程對比如下:
? 一個進(jìn)程可以有多個線程,但是至少有一個主線程
? 一個線程只能屬于一個進(jìn)程
? 一個進(jìn)程中多個線程,可以共享進(jìn)程中提供的數(shù)據(jù)
?CPU 運(yùn)算分配給線程,CPU 上執(zhí)行運(yùn)算的是線程
? 線程是最小的運(yùn)行單元,進(jìn)程是最小的資源管理單元
3. 串行、并行、并發(fā)
串行:就是傳統(tǒng)意義上的同步、順序的意思,按照一定的執(zhí)行步驟順序執(zhí)行每個環(huán)節(jié)
并行:就是傳統(tǒng)意義上的異步、同時的意思,同時執(zhí)行接受到的多個任務(wù)
并發(fā):同時接收到多個任務(wù),同時執(zhí)行多個任務(wù),但是具體到某個時刻~只是在執(zhí)行一個任 務(wù),只是在很短時間內(nèi)在多個任務(wù)之間切換,模擬形成了多個任務(wù)同時執(zhí)行的現(xiàn)象
4. 多線程編程
PYTHON本身對于多線程并發(fā)機(jī)制的支持是比較完善的
在PYTHON2中提供了標(biāo)準(zhǔn)模塊 thread 和 threading 支持多線程的并發(fā)編程 但是隨著并發(fā)編程的實(shí)際使用操作過程,thread 模塊過于底層的控制方式對于并發(fā)編程的 新手來說挺不是非常友好,要求多線程的程序開發(fā)邏輯思維清晰同時又具備大量開發(fā)經(jīng)驗(yàn)的 情況下,可以控制的非常精細(xì)。
PYTHON3中將 thread 模塊進(jìn)行了規(guī)范內(nèi)置,更名為_thread,友好的提醒如果你不是并發(fā)編 程的骨灰級愛好者,請不要輕易嘗試使用_thread 進(jìn)行操作,而是推薦使用操作更加靈活使 用更加簡潔的 threading 模塊進(jìn)行并發(fā)編程的處理。
1. Threading模塊屬性和方法
名稱??????????????? 描述
Thread?????????????線程類,用于創(chuàng)建和管理線程
Event???????????????? 事件類,用于線程同步
Condition????????????條件類,用于線程同步
Lock/RLock????????????鎖類,用于線程同步
Timer?????????????延時線程,用于在一定事件后執(zhí)行一個函數(shù)
Semaphore/BoundedSemaphore??????? 信號量類,用于線程同步
active_count()/activeCount()?????????獲取當(dāng)前
alive?????????????狀態(tài)的所有線程數(shù)量
current_thread()/currentThread()??????? 獲取當(dāng)期正在執(zhí)行的線程對象
get_ident()?????????? 獲取運(yùn)行中程序當(dāng)前線程的唯一編號
enumerate()????????????獲取所有
alive?????????? 狀態(tài)線程列表
local?????????????線程局部數(shù)據(jù)類
stack_size([size])???????????獲取線程占用內(nèi)存棧的大小
main_thread()???????????獲取主線程
2. Thread類型屬性和方法
名稱????????????描述
__init__(group,target,name,args,kwargs)????? 構(gòu)造方法,創(chuàng)建線程類型
is_alive()/isAlive()????????? 判斷當(dāng)前線程是否
alive?????????? 狀態(tài)
run()?????????????線程執(zhí)行方法,自定義線程必須重寫該函數(shù)
start()?????????????線程啟動方法
join([timeout=None])??????????線程獨(dú)占,等待當(dāng)前線程運(yùn)行結(jié)束或者超時
ident?????????????標(biāo)識當(dāng)前線程的唯一編號
name?????????? 當(dāng)前線程名稱
daemon?????????????布爾值,判斷當(dāng)前線程是否守護(hù)線程
3. 線程管理-事件[Event]
線程鎖解決了多個線程訪問共享數(shù)據(jù)時沖突的問題,如果多個線程之間需要通信應(yīng)該怎么解決呢?此時就需要用到多個線程之間的可以用于互相通信的處理對象了,該處理對象必須滿足如下基本條件
? 該對象能同時被多個線程訪問
? 該對象可以被標(biāo)記不同的狀態(tài)
? 該對象可以用于控制線程等待|運(yùn)行之間的切換
python提供了一個事件對象 Event,可以基本滿足上述條件,完成線程之間的通信
名稱???????? 描述
set()???????????添加一個標(biāo)記狀態(tài)
isSet()/is_set()??????? 檢查事件對象是否被標(biāo)記
clear()???????????清除標(biāo)記狀態(tài)
wait()???????????事件對象操作的當(dāng)前線程等待,直到該對象被標(biāo)記狀態(tài)
4. 線程管理-條件[Condition]
線程條件Condition對象,也是多線程并發(fā)模式下一種線程之間通信的友好支持 在某些情況下,我們需要多個線程在運(yùn)行過程中根據(jù)實(shí)際操作情況,不同功能的線程在滿足 對應(yīng)的條件時等待、啟動兩種狀態(tài)之間進(jìn)行切換
如經(jīng)典的線程間通信問題:生產(chǎn)者消費(fèi)者問題生產(chǎn)者負(fù)責(zé)生產(chǎn)食物,將食物存儲在列表中;消費(fèi)者負(fù)責(zé)消費(fèi),也就是從列表中刪除數(shù)據(jù);
這里的存儲食物的列表,我們限制了長度,最多容納20個食物數(shù)據(jù)
此時就會出現(xiàn)這樣的問題:如果列表中的食物已經(jīng)達(dá)到20;那么所有的生產(chǎn)者線程不能繼 續(xù)生產(chǎn)食物了,必須處于等待狀態(tài),等待消費(fèi)者消費(fèi)了食物之后再次生產(chǎn) 同理,如果列表中的食物為空了,所有的消費(fèi)者也就不能吃食物了,必須處于等待狀態(tài);等 待生產(chǎn)者生產(chǎn)了食物之后才能消費(fèi)
Condition對象的屬性和方法
名稱??????????描述
acquire()????????? 鎖定
release()????????? 解鎖
wait()???????????釋放鎖,同時阻塞當(dāng)前線程,等待被喚醒
wait_for()??????????釋放鎖,同時阻塞當(dāng)前線程,等待被喚醒
notify()???????????喚醒
notify_all()???????? 喚醒所有等待該condition條件的線程
5. 線程管理-隊(duì)列[Queue]
多線程并發(fā)編程的重點(diǎn),是線程之間共享數(shù)據(jù)的訪問問題和線程之間的通信問題為了解決線程之間數(shù)據(jù)共享問題,PYTHON提供了一個數(shù)據(jù)類型【隊(duì)列】可以用于在多線程 并發(fā)模式下,安全的訪問數(shù)據(jù)而不會造成數(shù)據(jù)共享沖突
python中的 queue 模塊提供的隊(duì)列類型 Queue 的操作模式如下
名稱????????????????描述
put([timeout=None])?????????????向隊(duì)列中添加數(shù)據(jù),隊(duì)列如果滿了,一直阻塞直到超時或者隊(duì) 列中有數(shù)據(jù)被刪除之后添加成功
get([timeout=None])??????????從隊(duì)列中獲取數(shù)據(jù),如果隊(duì)列為空,一直阻塞直到超時或者隊(duì)列中添加數(shù)據(jù)之后獲取成功
6. 線程管理-其他
PYTHON提供的線程同步管理方式還有其他的操作處理類型,操作方式都是大同小異,也分 別適用于不同的場景
名稱????????????????????描述
Semaphore????????????線程鎖計(jì)數(shù)器調(diào)用acquire()方法時該計(jì)數(shù)器減 1,調(diào)用 release()方法時計(jì)數(shù)器加 1 適用于控制線程訪問數(shù)量的場景下
BoundedSemaphore???????????Semaphore的派生類/子類,支持 with 關(guān)鍵字操作功能和使用場景同上
Barrier?????????????線程協(xié)同類型wait()方法:比較特殊,程序中的每個線程都可以調(diào)用該wait()方法,讓當(dāng)前 線程處于等待狀態(tài);直到所有的線程全部調(diào)用了wait()方法之后,所有線程同時喚醒繼續(xù)執(zhí)行。比較適用于數(shù)據(jù)預(yù)處理工作的場景
5. 多進(jìn)程編程
進(jìn)程是正在執(zhí)行中的應(yīng)用程序,一個進(jìn)程包含了該應(yīng)用程序的所有信息,如加載數(shù)據(jù)內(nèi)存空間、代碼、程序數(shù)據(jù)、對象句柄,執(zhí)行單元等等,一個應(yīng)用程序根據(jù)其功能的多樣性,可以通過多個進(jìn)程并發(fā)的形式來實(shí)現(xiàn)。
計(jì)算機(jī)中多線程的操作已經(jīng)可以實(shí)現(xiàn)多任務(wù)的處理機(jī)制了,但是如果涉及到多核CPU或者 多個 CPU 的硬件主機(jī),多進(jìn)程并發(fā)編程的實(shí)現(xiàn)能比多線程并發(fā)機(jī)制更加有效的利用和發(fā)揮 硬件資源優(yōu)勢。
1. Multiprocessing
PYTHON內(nèi)建標(biāo)準(zhǔn)模塊 multiprocessing 對多進(jìn)程并發(fā)編程提供了良好的支持,通過該模塊 的 Process 進(jìn)程類型,可以很方便的創(chuàng)建和管理多個進(jìn)程;通過該模塊提供的 Lock|RLock 進(jìn) 程鎖類型、Event 事件類型、Condition 條件類型等等也可以很方便的完成進(jìn)程間同步操作。
和多線程的操作方式類似,多進(jìn)程的實(shí)現(xiàn)方式也提供了面向過程的實(shí)現(xiàn)和面向?qū)ο蟮膶?shí)現(xiàn)同時多進(jìn)程的本地?cái)?shù)據(jù)共享和通信模式也非常的類似多線程編程
multiprocessing常見屬性和方法
名稱???????????????? 描述
Process??????????????進(jìn)程類型,用于創(chuàng)建和管理進(jìn)程
Lock|RLock???????????? 進(jìn)程互斥鎖|重用鎖,用于進(jìn)程同步
Event??????????????????進(jìn)程事件類型,用于進(jìn)程同步
Condition?????????????????進(jìn)程條件類型,用于進(jìn)程同步
Queue??????????????????進(jìn)程隊(duì)列類型,用于多進(jìn)程數(shù)據(jù)共享
Manager??????????????????進(jìn)程管理類型,用于多進(jìn)程數(shù)據(jù)共享
Listener|Client????????????????進(jìn)程監(jiān)聽|客戶端,基于網(wǎng)絡(luò)多進(jìn)程之間的數(shù)據(jù)共享
2. Multiprocessing
多進(jìn)程的操作在實(shí)際應(yīng)用中也是非常多的,但是純底層的代碼開發(fā)控制并發(fā)也是一件非常繁瑣的事情,所以就出現(xiàn)了面向過程多進(jìn)程并發(fā)的優(yōu)化操作方式:進(jìn)程池Pool
通過進(jìn)程池Pool可以快速創(chuàng)建多個進(jìn)程執(zhí)行指定函數(shù),完成高并發(fā)處理操作
(1) Pool對象的屬性和方法
名稱?????????????描述
apply(func, args)??????? 傳遞參數(shù)args并執(zhí)行函數(shù) func,同時阻塞當(dāng)前進(jìn)程直到該函數(shù)執(zhí)行完成,函數(shù)func只會在進(jìn)程池中的一個進(jìn)程中運(yùn)行
apply_async(???func,args,callback,?error_callback??)??????????????????????????傳遞參數(shù)args并執(zhí)行函數(shù) func,該方法不會形成阻塞函數(shù)執(zhí)行完成之后可以通過結(jié)果對象的get()方法獲取結(jié)果如果結(jié)果對象可用時會自動調(diào)用callback指定的函數(shù)如果結(jié)果對象調(diào)用失敗時會自動調(diào)用error_callback指定的函數(shù)
close()????????????????????? Pool進(jìn)程池的底層工作機(jī)制是向進(jìn)程池提交任務(wù)產(chǎn)生工作進(jìn)程執(zhí)行該方法是主動停止給進(jìn)程池提交任務(wù),并等待所有提交任務(wù)執(zhí)行完成退出
terminate()?????????????????立即結(jié)束該進(jìn)程,當(dāng)進(jìn)程池對象被回收時自動調(diào)用該方法
join()????????????????????????? 等待工作進(jìn)程退出,再次之間必須調(diào)用close()或者 teminate
3. 多個進(jìn)程通信:multiprocessing.Manager
不同線程之間的數(shù)據(jù)通信,涉及到核心的數(shù)據(jù)共享問題,主要由PYTHON中提供的內(nèi)建模 塊 multiprocessing.Manager 類型實(shí)現(xiàn),該類型內(nèi)置了大量的用于數(shù)據(jù)共享的操作
multiprocessing.Manager常見屬性和方法 ??
名稱?????????????? 描述
Array????????????????內(nèi)置進(jìn)程間共享數(shù)組類型
Queue????????????????內(nèi)置進(jìn)程間共享隊(duì)列類型
list()????????????????????內(nèi)置進(jìn)程間共享列表類型
dict()??????????????????? 內(nèi)置進(jìn)程間共享字典類型
Value????????????????????內(nèi)置進(jìn)程間共享值類型
Barrier????????????????????????進(jìn)程同步類型
BoundedSemaphore| Semaphore??????進(jìn)程信號量類型
Lock|RLock???????????????進(jìn)程互斥鎖/重用鎖
Event????????????????進(jìn)程同步事件類型
Condition???????????????進(jìn)程同步條件類型
多個進(jìn)程之間的通信操作,數(shù)據(jù)的傳遞在PYTHON中的 multiprocessing 模塊中提供了一個 專門用于多進(jìn)程之間進(jìn)行數(shù)據(jù)傳遞的隊(duì)列:Queue
4. 多個進(jìn)程通信:multiprocessing.Queue
multiprocessing.Queue常見屬性和方法
名稱????????????? 描述
put(data [, timeout=None])?????????? 添加一個數(shù)據(jù)到隊(duì)列中
put_nowait(data)???????????????????? 添加一個數(shù)據(jù)到隊(duì)列中,非阻塞模式
get([timeout=None])????????????從隊(duì)列中獲取一個數(shù)據(jù)
get_nowait()????????????????? 從隊(duì)列中獲取一個數(shù)據(jù),非阻塞模式
full()?????????????????????????? 判斷隊(duì)列是否已滿
empty()?????????????????? 判斷隊(duì)列是否已空
close()???????????????????關(guān)閉隊(duì)列
qsize()???????????????????獲取隊(duì)列中的元素?cái)?shù)量
5. 多個進(jìn)程通信:multiprocessing.Pipe
PYTHON為了更加友好的多個進(jìn)程之間的數(shù)據(jù)通信操作,提供了一個管道類型專門用于進(jìn)程之間的協(xié)作:multiprocessing.Pipe
multiprocessing.Pipe常見屬性和方法
名稱????????????????描述
__init__(duplex=True)???????????????? 初始化方法,返回兩個數(shù)據(jù)conn1,conn2分別表示管道的兩端,默認(rèn)是雙向通信如果duplex=False conn1只能接受消息,conn2只能發(fā)送消息
send(data)???????????????????????????????????發(fā)送消息
recv()????????????????????????????????????????????接受消息