當前位置:首頁 » 編程語言 » python進程狀態

python進程狀態

發布時間: 2022-12-28 21:22:45

『壹』 python能檢測軟體狀態嗎

python是能檢測軟體運行狀態的。具體代碼如下:
首先我們需要首先注意的一個地方是配置文件的後綴。
vim /etc/supervisord.conf
[include]
files = supervisord.d/*.ini
如果你想配置文件為其他格式,比如 conf 格式的話, 需要更改 iles = supervisord.d/*.conf 。
比如我們需要守護啟動一個進程,我們就以守護Prometheus 為例:
vim /etc/supervisord.d/proms.ini
[program:proms]
command=/opt/prometheus/server/prometheus/prometheus
directory=/opt/prometheus/server/prometheus
stdout_logfile=/home/data/logs/prometheus/sever.log
autostart=true
autorestart=true
redirect_stderr=true
user=root
startsecs=3
supervisor配置文件詳解:
program: 指定的守護進程名
command: 命令
stdout_logfile: 日誌路徑
autostart: supervisor啟動的時候是否隨著同時啟動,默認為 true
autorestart: 是否掛了自動重啟
redirect_stderr:標准錯誤重定向
startsecs: 子進程啟動多少秒之後,此時的狀態是running
啟動supervisor--(yum方式安裝的)
/usr/bin/python /usr/bin/supervisord -c /etc/supervisord.conf

『貳』 Python:進程(threading)

這里是自己寫下關於 Python 跟進程相關的 threading 模塊的一點筆記,跟有些跟 Linux 調用挺像的,有共通之處。

https://docs.python.org/3/library/threading.html?highlight=threading#thread-objects

直接傳入

繼承 Thread 重寫 run 方法

threading.Thread(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None)

group 線程組,未實現

start() 線程就緒
join([timeout]) 阻塞其他線程,直到調用這方法的進程結束或時間到達

RuntimeError: cannot join thread before it is started

get/setName(name) 獲取/設置線程名。
isAlive() 返回線程是否在運行。
is/setDaemon(bool): 獲取/設置是後台線程(默認前台線程(False))。(在start之前設置)

The entire Python program exits when no alive non-daemon threads are left.
沒有非後台進程運行,Python 就退出。
主線程執行完畢後,後台線程不管是成功與否,主線程均停止

t.start()
t.join()
start() 後 join() 會順序執行,失去線程意義

https://docs.python.org/3/library/threading.html?#lock-objects

Lock屬於全局,Rlock屬於線程(R的意思是可重入,線程用Lock的話會死鎖,來看例子)

acquire(blocking=True, timeout=-1) 申請鎖,返回申請的結果
release() 釋放鎖,沒返回結果

https://docs.python.org/3/library/threading.html#condition-objects

可以在構造時傳入rlock lock實例,不然自己生成一個。

acquire([timeout])/release(): 與lock rlock 相同
wait([timeout]): 調用這個方法將使線程進入等待池,並釋放鎖。調用方法前線程必須已獲得鎖定,否則將拋出異常。
notify(): 調用這個方法將從等待池挑選一個線程並通知,收到通知的線程將自動調用acquire()嘗試獲得鎖定(進入鎖定池);其他線程仍然在等待池中。調用這個方法不會釋放鎖定。調用方法前線程必須已獲得鎖定,否則將拋出異常。
notifyAll(): 調用這個方法將通知等待池中所有的線程,這些線程都將進入鎖定池嘗試獲得鎖定。調用這個方法不會釋放鎖定。使用前線程必須已獲得鎖定,否則將拋出異常。

threading.Semaphore(value=1)

https://docs.python.org/3/library/threading.html#semaphore-objects

acquire(blocking=True, timeout=None)
資源數大於0,減一並返回,等於0時等待,blocking為False不阻塞進程
返回值是申請結果
release()
資源數加1

https://docs.python.org/3/library/threading.html#event-objects

事件內置了一個初始為False的標志

is_set() 返回內置標志的狀態
set() 設為True
clear() 設為False
wait(timeout=None) 阻塞線程並等待,為真時返回。返回值只會在等待超時時為False,其他情況為True

https://docs.python.org/3/library/threading.html#timer-objects

threading.Timer(interval, function, args=None, kwargs=None)

第一個參數是時間間隔,單位是秒,整數或者浮點數,負數不會報錯直接執行不等待
可以用cancel() 取消

https://docs.python.org/3/library/threading.html#barrier-objects

threading.Barrier(parties, action=None, timeout=None)

調用的進程數目達到第一個設置的參數就喚醒全部進程

wait(timeout=None)
reset() 重置,等待中的進程收到 BrokenBarrierError 錯誤

『叄』 Python多進程運行——Multiprocessing基礎教程2

上篇文章簡單介紹了multiprocessing模塊,本文將要介紹進程之間的數據共享和信息傳遞的概念。

在多進程處理中,所有新創建的進程都會有這兩個特點:獨立運行,有自己的內存空間。

我們來舉個例子展示一下:

這個程序的輸出結果是:

在上面的程序中我們嘗試在兩個地方列印全局列表result的內容:

我們再用一張圖來幫助理解記憶不同進程間的數據關系:

如果程序需要在不同的進程之間共享一些數據的話,該怎麼做呢?不用擔心,multiprocessing模塊提供了Array對象和Value對象,用來在進程之間共享數據。

所謂Array對象和Value對象分別是指從共享內存中分配的ctypes數組和對象。我們直接來看一個例子,展示如何用Array對象和Value對象在進程之間共享數據:

程序輸出的結果如下:

成功了!主程序和p1進程輸出了同樣的結果,說明程序中確實完成了不同進程間的數據共享。那麼我們來詳細看一下上面的程序做了什麼:

在主程序中我們首先創建了一個Array對象:

向這個對象輸入的第一個參數是數據類型:i表示整數,d代表浮點數。第二個參數是數組的大小,在這個例子中我們創建了包含4個元素的數組。

類似的,我們創建了一個Value對象:

我們只對Value對象輸入了一個參數,那就是數據類型,與上述的方法一致。當然,我們還可以對其指定一個初始值(比如10),就像這樣:

隨後,我們在創建進程對象時,將剛創建好的兩個對象:result和square_sum作為參數輸入給進程:

在函數中result元素通過索引進行數組賦值,square_sum通過 value 屬性進行賦值。

注意:為了完整列印result數組的結果,需要使用 result[:] 進行列印,而square_sum也需要使用 value 屬性進行列印:

每當python程序啟動時,同時也會啟動一個伺服器進程。隨後,只要我們需要生成一個新進程,父進程就會連接到伺服器並請求它派生一個新進程。這個伺服器進程可以保存Python對象,並允許其他進程使用代理來操作它們。

multiprocessing模塊提供了能夠控制伺服器進程的Manager類。所以,Manager類也提供了一種創建可以在不同流程之間共享的數據的方法。

伺服器進程管理器比使用共享內存對象更靈活,因為它們可以支持任意對象類型,如列表、字典、隊列、值、數組等。此外,單個管理器可以由網路上不同計算機上的進程共享。

但是,伺服器進程管理器的速度比使用共享內存要慢。

讓我們來看一個例子:

這個程序的輸出結果是:

我們來理解一下這個程序做了什麼:首先我們創建了一個manager對象

在with語句下的所有行,都是在manager對象的范圍內的。接下來我們使用這個manager對象創建了列表(類似的,我們還可以用 manager.dict() 創建字典)。

最後我們創建了進程p1(用於在records列表中插入一條新的record)和p2(將records列印出來),並將records作為參數進行傳遞。

伺服器進程的概念再次用下圖總結一下:

為了能使多個流程能夠正常工作,常常需要在它們之間進行一些通信,以便能夠劃分工作並匯總最後的結果。multiprocessing模塊支持進程之間的兩種通信通道:Queue和Pipe。

使用隊列來回處理多進程之間的通信是一種比較簡單的方法。任何Python對象都可以使用隊列進行傳遞。我們來看一個例子:

上面這個程序的輸出結果是:

我們來看一下上面這個程序到底做了什麼。首先我們創建了一個Queue對象:

然後,將這個空的Queue對象輸入square_list函數。該函數會將列表中的數平方,再使用 put() 方法放入隊列中:

隨後使用 get() 方法,將q列印出來,直至q重新稱為一個空的Queue對象:

我們還是用一張圖來幫助理解記憶:

一個Pipe對象只能有兩個端點。因此,當進程只需要雙向通信時,它會比Queue對象更好用。

multiprocessing模塊提供了 Pipe() 函數,該函數返回由管道連接的一對連接對象。 Pipe() 返回的兩個連接對象分別表示管道的兩端。每個連接對象都有 send() 和 recv() 方法。

我們來看一個例子:

上面這個程序的輸出結果是:

我們還是來看一下這個程序到底做了什麼。首先創建了一個Pipe對象:

與上文說的一樣,該對象返回了一對管道兩端的兩個連接對象。然後使用 send() 方法和 recv() 方法進行信息的傳遞。就這么簡單。在上面的程序中,我們從一端向另一端發送一串消息。在另一端,我們收到消息,並在收到END消息時退出。

要注意的是,如果兩個進程(或線程)同時嘗試從管道的同一端讀取或寫入管道中的數據,則管道中的數據可能會損壞。不過不同的進程同時使用管道的兩端是沒有問題的。還要注意,Queue對象在進程之間進行了適當的同步,但代價是增加了計算復雜度。因此,Queue對象對於線程和進程是相對安全的。

最後我們還是用一張圖來示意:

Python的multiprocessing模塊還剩最後一篇文章:多進程的同步與池化

敬請期待啦!

『肆』 關於python多進程使用(Queue、生產者和消費者)

關於 的生產者和消費者的實現,剛好最近有用到,簡單總結記錄下:

是系統獨立調度核分配系統資源(CPU、內存)的基本單位,進程之間是相互獨立的,每啟動一個新的進程相當於把數據進行了一次克隆。
python提供了多種方法實現了多進程中間的 (可以修改同一份數據)。

GIL 的全稱是 Global Interpreter Lock(全局解釋器鎖),來源是 Python 設計之初的考慮,為了數據安全所做的決定。
某個線程想要執行,必須先拿到 GIL,我們可以把 GIL 看作是「通行證」,並且在一個 Python 進程中,GIL 只有一個,這就導致了多線程搶佔GIL耗時。這就是為什麼在多核CPU上,Python 的多線程效率並不高的根本原因。
所以有必要學習下多進程的使用。

『伍』 關於python 命令控製程序啟動與結束

可以使用一個標志變數來控製程序的啟動和結束。
首先,在主程序中設置一個標志變數,例如 running,用於指示程序是否處於運行狀態。在程序開始時,running 應設置為 False。
然後,在每次循環中檢查 running 的值。如果 running 為 True,則執行 auto() 函數;如果 running 為 False,則等待用戶輸入命令。
當用戶輸入 qd 命令時,將 running 設置為 True,並執行 auto() 函數。當用戶輸入 tz 命令時,將 running 設置為 False,並執行 reset() 函數。
示例代碼如下:
running
running = False
while True:
cmd = input("請輸入命令:")
if cmd == 'qd':
running = True
elif cmd == 'tz':
running = False
if running:
auto()
else:
reset()
在這段代碼中,我們使用了一個 while 循環來不斷接收用戶的命令。在每次循環中,我們會讀入用戶的命令,並根據命令的不同設置 running 的值。如果 running 為 True,則執行 auto() 函數;如果 running 為 False,則執行 reset() 函數。
這樣,用戶就可以隨時輸入 tz 命令來停止程序,也可以輸入 qd 命令來重新啟動程序。
希望這些信息能夠幫助您。

『陸』 python如何獲取進程和線程狀態

threading.active_count()
Return the number of Thread objects currently alive. The returned count is equal to the length of the list returned by enumerate().
active_count可以返回當前活動的線程枚舉
我一般是這么用的

def getHeatsParallel(self): threads = [] for i in range(0, self.threadCount): t = threading.Thread(target=self.SomeFunction, name=str(i)) threads.append(t) t.start() for t in threads: t.join()

『柒』 python中的進程-實戰部分

如果想了解進程 可以先看一下這一篇 python中的進程-理論部分

python中的多線程無法利用多核優勢,如果想要充分地使用多核CPU的資源(os.cpu_count()查看),在python中大部分情況需要使用多進程。Python提供了multiprocessing。
multiprocessing模塊用來開啟子進程,並在子進程中執行我們定製的任務(比如函數),該模塊與多線程模塊threading的編程介面類似。

multiprocessing模塊的功能眾多:支持子進程、通信和共享數據、執行不同形式的同步,提供了Process、Queue、Pipe、Lock等組件。

需要再次強調的一點是:與線程不同,進程沒有任何共享狀態,進程修改的數據,改動僅限於該進程內。

創建進程的類

參數介紹:

group參數未使用,值始終為None

target表示調用對象,即子進程要執行的任務

args表示調用對象的位置參數元組,args=(1,2,'tiga',)

kwargs表示調用對象的字典,kwargs={'name':'tiga','age':18}

name為子進程的名稱

方法介紹:

p.start():啟動進程,並調用該子進程中的p.run()
p.run():進程啟動時運行的方法,正是它去調用target指定的函數,我們自定義類的類中一定要實現該方法

p.terminate():強制終止進程p,不會進行任何清理操作,如果p創建了子進程,該子進程就成了僵屍進程,使用該方法需要特別小心這種情況。如果p還保存了一個鎖那麼也將不會被釋放,進而導致死鎖
p.is_alive():如果p仍然運行,返回True

p.join([timeout]):主線程等待p終止(強調:是主線程處於等的狀態,而p是處於運行的狀態)。timeout是可選的超時時間,需要強調的是,p.join只能join住start開啟的進程,而不能join住run開啟的進程

屬性介紹:

注意:在windows中Process()必須放到# if __name__ == '__main__':下

創建並開啟子進程的兩種方式

方法一:


方法二:

有了join,程序不就是串列了嗎???

terminate與is_alive

name與pid

『捌』 一篇文章帶你深度解析Python線程和進程

使用Python中的線程模塊,能夠同時運行程序的不同部分,並簡化設計。如果你已經入門Python,並且想用線程來提升程序運行速度的話,希望這篇教程會對你有所幫助。

線程與進程

什麼是進程

進程是系統進行資源分配和調度的一個獨立單位 進程是具有一定獨立功能的程序關於某個數據集合上的一次運行活動,進程是系統進行資源分配和調度的一個獨立單位。每個進程都有自己的獨立內存空間,不同進程通過進程間通信來通信。由於進程比較重量,占據獨立的內存,所以上下文進程間的切換開銷(棧、寄存器、虛擬內存、文件句柄等)比較大,但相對比較穩定安全。

什麼是線程

CPU調度和分派的基本單位 線程是進程的一個實體,是CPU調度和分派的基本單位,它是比進程更小的能獨立運行的基本單位.線程自己基本上不擁有系統資源,只擁有一點在運行中必不可少的資源(如程序計數器,一組寄存器和棧),但是它可與同屬一個進程的其他的線程共享進程所擁有的全部資源。線程間通信主要通過共享內存,上下文切換很快,資源開銷較少,但相比進程不夠穩定容易丟失數據。

進程與線程的關系圖

線程與進程的區別:

進程

現實生活中,有很多的場景中的事情是同時進行的,比如開車的時候 手和腳共同來駕駛 汽車 ,比如唱歌跳舞也是同時進行的,再比如邊吃飯邊打電話;試想如果我們吃飯的時候有一個領導來電,我們肯定是立刻就接聽了。但是如果你吃完飯再接聽或者回電話,很可能會被開除。

注意:

多任務的概念

什麼叫 多任務 呢?簡單地說,就是操作系統可以同時運行多個任務。打個比方,你一邊在用瀏覽器上網,一邊在聽MP3,一邊在用Word趕作業,這就是多任務,至少同時有3個任務正在運行。還有很多任務悄悄地在後台同時運行著,只是桌面上沒有顯示而已。

現在,多核CPU已經非常普及了,但是,即使過去的單核CPU,也可以執行多任務。由於CPU執行代碼都是順序執行的,那麼,單核CPU是怎麼執行多任務的呢?

答案就是操作系統輪流讓各個任務交替執行,任務1執行0.01秒,切換到任務2,任務2執行0.01秒,再切換到任務3,執行0.01秒,這樣反復執行下去。表面上看,每個任務都是交替執行的,但是,由於CPU的執行速度實在是太快了,我們感覺就像所有任務都在同時執行一樣。

真正的並行執行多任務只能在多核CPU上實現,但是,由於任務數量遠遠多於CPU的核心數量,所以,操作系統也會自動把很多任務輪流調度到每個核心上執行。 其實就是CPU執行速度太快啦!以至於我們感受不到在輪流調度。

並行與並發

並行(Parallelism)

並行:指兩個或兩個以上事件(或線程)在同一時刻發生,是真正意義上的不同事件或線程在同一時刻,在不同CPU資源呢上(多核),同時執行。

特點

並發(Concurrency)

指一個物理CPU(也可以多個物理CPU) 在若幹道程序(或線程)之間多路復用,並發性是對有限物理資源強制行使多用戶共享以提高效率。

特點

multiprocess.Process模塊

process模塊是一個創建進程的模塊,藉助這個模塊,就可以完成進程的創建。

語法:Process([group [, target [, name [, args [, kwargs]]]]])

由該類實例化得到的對象,表示一個子進程中的任務(尚未啟動)。

注意:1. 必須使用關鍵字方式來指定參數;2. args指定的為傳給target函數的位置參數,是一個元祖形式,必須有逗號。

參數介紹:

group:參數未使用,默認值為None。

target:表示調用對象,即子進程要執行的任務。

args:表示調用的位置參數元祖。

kwargs:表示調用對象的字典。如kwargs = {'name':Jack, 'age':18}。

name:子進程名稱。

代碼:

除了上面這些開啟進程的方法之外,還有一種以繼承Process的方式開啟進程的方式:

通過上面的研究,我們千方百計實現了程序的非同步,讓多個任務可以同時在幾個進程中並發處理,他們之間的運行沒有順序,一旦開啟也不受我們控制。盡管並發編程讓我們能更加充分的利用IO資源,但是也給我們帶來了新的問題。

當多個進程使用同一份數據資源的時候,就會引發數據安全或順序混亂問題,我們可以考慮加鎖,我們以模擬搶票為例,來看看數據安全的重要性。

加鎖可以保證多個進程修改同一塊數據時,同一時間只能有一個任務可以進行修改,即串列的修改。加鎖犧牲了速度,但是卻保證了數據的安全。

因此我們最好找尋一種解決方案能夠兼顧:1、效率高(多個進程共享一塊內存的數據)2、幫我們處理好鎖問題。

mutiprocessing模塊為我們提供的基於消息的IPC通信機制:隊列和管道。隊列和管道都是將數據存放於內存中 隊列又是基於(管道+鎖)實現的,可以讓我們從復雜的鎖問題中解脫出來, 我們應該盡量避免使用共享數據,盡可能使用消息傳遞和隊列,避免處理復雜的同步和鎖問題,而且在進程數目增多時,往往可以獲得更好的可獲展性( 後續擴展該內容 )。

線程

Python的threading模塊

Python 供了幾個用於多線程編程的模塊,包括 thread, threading 和 Queue 等。thread 和 threading 模塊允許程序員創建和管理線程。thread 模塊 供了基本的線程和鎖的支持,而 threading 供了更高級別,功能更強的線程管理的功能。Queue 模塊允許用戶創建一個可以用於多個線程之間 共享數據的隊列數據結構。

python創建和執行線程

創建線程代碼

1. 創建方法一:

2. 創建方法二:

進程和線程都是實現多任務的一種方式,例如:在同一台計算機上能同時運行多個QQ(進程),一個QQ可以打開多個聊天窗口(線程)。資源共享:進程不能共享資源,而線程共享所在進程的地址空間和其他資源,同時,線程有自己的棧和棧指針。所以在一個進程內的所有線程共享全局變數,但多線程對全局變數的更改會導致變數值得混亂。

代碼演示:

得到的結果是:

首先需要明確的一點是GIL並不是Python的特性,它是在實現Python解析器(CPython)時所引入的一個概念。就好比C++是一套語言(語法)標准,但是可以用不同的編譯器來編譯成可執行代碼。同樣一段代碼可以通過CPython,PyPy,Psyco等不同的Python執行環境來執行(其中的JPython就沒有GIL)。

那麼CPython實現中的GIL又是什麼呢?GIL全稱Global Interpreter Lock為了避免誤導,我們還是來看一下官方給出的解釋:

主要意思為:

因此,解釋器實際上被一個全局解釋器鎖保護著,它確保任何時候都只有一個Python線程執行。在多線程環境中,Python 虛擬機按以下方式執行:

由於GIL的存在,Python的多線程不能稱之為嚴格的多線程。因為 多線程下每個線程在執行的過程中都需要先獲取GIL,保證同一時刻只有一個線程在運行。

由於GIL的存在,即使是多線程,事實上同一時刻只能保證一個線程在運行, 既然這樣多線程的運行效率不就和單線程一樣了嗎,那為什麼還要使用多線程呢?

由於以前的電腦基本都是單核CPU,多線程和單線程幾乎看不出差別,可是由於計算機的迅速發展,現在的電腦幾乎都是多核CPU了,最少也是兩個核心數的,這時差別就出來了:通過之前的案例我們已經知道,即使在多核CPU中,多線程同一時刻也只有一個線程在運行,這樣不僅不能利用多核CPU的優勢,反而由於每個線程在多個CPU上是交替執行的,導致在不同CPU上切換時造成資源的浪費,反而會更慢。即原因是一個進程只存在一把gil鎖,當在執行多個線程時,內部會爭搶gil鎖,這會造成當某一個線程沒有搶到鎖的時候會讓cpu等待,進而不能合理利用多核cpu資源。

但是在使用多線程抓取網頁內容時,遇到IO阻塞時,正在執行的線程會暫時釋放GIL鎖,這時其它線程會利用這個空隙時間,執行自己的代碼,因此多線程抓取比單線程抓取性能要好,所以我們還是要使用多線程的。

GIL對多線程Python程序的影響

程序的性能受到計算密集型(CPU)的程序限制和I/O密集型的程序限制影響,那什麼是計算密集型和I/O密集型程序呢?

計算密集型:要進行大量的數值計算,例如進行上億的數字計算、計算圓周率、對視頻進行高清解碼等等。這種計算密集型任務雖然也可以用多任務完成,但是花費的主要時間在任務切換的時間,此時CPU執行任務的效率比較低。

IO密集型:涉及到網路請求(time.sleep())、磁碟IO的任務都是IO密集型任務,這類任務的特點是CPU消耗很少,任務的大部分時間都在等待IO操作完成(因為IO的速度遠遠低於CPU和內存的速度)。對於IO密集型任務,任務越多,CPU效率越高,但也有一個限度。

當然為了避免GIL對我們程序產生影響,我們也可以使用,線程鎖。

Lock&RLock

常用的資源共享鎖機制:有Lock、RLock、Semphore、Condition等,簡單給大家分享下Lock和RLock。

Lock

特點就是執行速度慢,但是保證了數據的安全性

RLock

使用鎖代碼操作不當就會產生死鎖的情況。

什麼是死鎖

死鎖:當線程A持有獨占鎖a,並嘗試去獲取獨占鎖b的同時,線程B持有獨占鎖b,並嘗試獲取獨占鎖a的情況下,就會發生AB兩個線程由於互相持有對方需要的鎖,而發生的阻塞現象,我們稱為死鎖。即死鎖是指多個進程因競爭資源而造成的一種僵局,若無外力作用,這些進程都將無法向前推進。

所以,在系統設計、進程調度等方面注意如何不讓這四個必要條件成立,如何確定資源的合理分配演算法,避免進程永久占據系統資源。

死鎖代碼

python線程間通信

如果各個線程之間各干各的,確實不需要通信,這樣的代碼也十分的簡單。但這一般是不可能的,至少線程要和主線程進行通信,不然計算結果等內容無法取回。而實際情況中要復雜的多,多個線程間需要交換數據,才能得到正確的執行結果。

python中Queue是消息隊列,提供線程間通信機制,python3中重名為為queue,queue模塊塊下提供了幾個阻塞隊列,這些隊列主要用於實現線程通信。

在 queue 模塊下主要提供了三個類,分別代表三種隊列,它們的主要區別就在於進隊列、出隊列的不同。

簡單代碼演示

此時代碼會阻塞,因為queue中內容已滿,此時可以在第四個queue.put('蘋果')後面添加timeout,則成為 queue.put('蘋果',timeout=1)如果等待1秒鍾仍然是滿的就會拋出異常,可以捕獲異常。

同理如果隊列是空的,無法獲取到內容默認也會阻塞,如果不阻塞可以使用queue.get_nowait()。

在掌握了 Queue 阻塞隊列的特性之後,在下面程序中就可以利用 Queue 來實現線程通信了。

下面演示一個生產者和一個消費者,當然都可以多個

使用queue模塊,可在線程間進行通信,並保證了線程安全。

協程

協程,又稱微線程,纖程。英文名Coroutine。

協程是python個中另外一種實現多任務的方式,只不過比線程更小佔用更小執行單元(理解為需要的資源)。為啥說它是一個執行單元,因為它自帶CPU上下文。這樣只要在合適的時機, 我們可以把一個協程 切換到另一個協程。只要這個過程中保存或恢復 CPU上下文那麼程序還是可以運行的。

通俗的理解:在一個線程中的某個函數,可以在任何地方保存當前函數的一些臨時變數等信息,然後切換到另外一個函數中執行,注意不是通過調用函數的方式做到的,並且切換的次數以及什麼時候再切換到原來的函數都由開發者自己確定。

在實現多任務時,線程切換從系統層面遠不止保存和恢復 CPU上下文這么簡單。操作系統為了程序運行的高效性每個線程都有自己緩存Cache等等數據,操作系統還會幫你做這些數據的恢復操作。所以線程的切換非常耗性能。但是協程的切換只是單純的操作CPU的上下文,所以一秒鍾切換個上百萬次系統都抗的住。

greenlet與gevent

為了更好使用協程來完成多任務,除了使用原生的yield完成模擬協程的工作,其實python還有的greenlet模塊和gevent模塊,使實現協程變的更加簡單高效。

greenlet雖說實現了協程,但需要我們手工切換,太麻煩了,gevent是比greenlet更強大的並且能夠自動切換任務的模塊。

其原理是當一個greenlet遇到IO(指的是input output 輸入輸出,比如網路、文件操作等)操作時,比如訪問網路,就自動切換到其他的greenlet,等到IO操作完成,再在適當的時候切換回來繼續執行。

模擬耗時操作:

如果有耗時操作也可以換成,gevent中自己實現的模塊,這時候就需要打補丁了。

使用協程完成一個簡單的二手房信息的爬蟲代碼吧!

以下文章來源於Python專欄 ,作者宋宋

文章鏈接:https://mp.weixin.qq.com/s/2r3_ipU3HjdA5VnqSHjUnQ

『玖』 Python管理Windows進程

用python獲得正在的運行的windows進程的有幾種方式:

通過 PyWin32 包對Windows進行處理。
可以通過這個獲取系統信息,但僅限於windows系統。

運行結果:

運行結果:

運行結果:

通過交互模式,使用WMI取得進程:

此方法可以跨平台,不過需要在安裝 psutil 包.

以上實現一個類似top的工具。

轉自 http://www.blog.pythonlibrary.org/2010/10/03/how-to-find-and-list-all-running-processes-with-python/

『拾』 簡述python進程,線程和協程的區別及應用場景

協程多與線程進行比較
1) 一個線程可以多個協程,一個進程也可以單獨擁有多個協程,這樣python中則能使用多核CPU。
2) 線程進程都是同步機制,而協程則是非同步
3) 協程能保留上一次調用時的狀態,每次過程重入時,就相當於進入上一次調用的狀態

熱點內容
java直播網站源碼 發布:2025-07-04 14:46:35 瀏覽:169
安卓應用市場消費記錄怎麼刪除 發布:2025-07-04 14:39:47 瀏覽:30
知道一個伺服器的ip地址 發布:2025-07-04 14:20:33 瀏覽:597
蘋果7鎖屏密碼怎麼改 發布:2025-07-04 14:04:44 瀏覽:710
P三零是什麼配置 發布:2025-07-04 13:58:41 瀏覽:361
哪個安卓機有長方形home鍵 發布:2025-07-04 13:43:58 瀏覽:861
android腳本錄制 發布:2025-07-04 13:17:47 瀏覽:342
嵌入式和安卓哪個硬體成本高 發布:2025-07-04 13:05:56 瀏覽:229
360代理伺服器怎麼設置 發布:2025-07-04 12:49:49 瀏覽:515
iphone在哪清除緩存 發布:2025-07-04 12:49:38 瀏覽:340