多進(jìn)程,多線程及其模塊

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()????????????????????????????????????????????接受消息

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 清醒了一晚上,想了一晚上。 不能再隨波逐流了。 我不想再圍著男人轉(zhuǎn)了,我的自尊呢?自己想要的東西,用自己的金錢獲得...
    詩亖閱讀 305評論 0 0
  • 昨日持續(xù)了一個月之久的“考試周”終告結(jié)束,和許久未交心朋友出去散心,卻聽聞她過的這般不好,起初并未在意,以...
    Lora蘿拉閱讀 612評論 0 1
  • 菜鳥學(xué)畫畫(彩鉛畫No.07) (亦濃) 繪畫步驟: 1.線稿 2.花瓣涂底色 3.花瓣疊色 4.細(xì)節(jié)強(qiáng)調(diào) 5.花...
    開在夜里的花兒閱讀 704評論 13 11

友情鏈接更多精彩內(nèi)容