python線程/進程真象(假的嗎?)

最近因爲工作需求,需要用下python,作爲項目需求,多線程和多進程首先要考慮進去。在網上trace相關的一些資料,總是發現一些人在說:python下面是假線程。不覺得有點驚奇,據我所知,連java裏面的線程對象(blue thread 虛擬機藍色線程)也是跟系統有很大關係,多半內部包含了一個真實的系統線程對象,而python據官方說,並不是如同go一樣是基於routine的,非真實線程 這種說法估計有誤。。

於是乎,做試驗:

代碼段:

註明:該代碼片斷的外圍還有4個線程執行該部分代碼,故此工作線程遠大於10個

直接spy 進程:

看見了嗎,裏面這麼多工作線程。。。

linux系統,簡單的把手上一個項目在linux上的trace結果發下:

看上圖最上出現4個 worker2,簡單點說就是一個 worker2主進程,並有3個其子進程(線程),上圖最下

顯示4個主進程,所以只有一個worker2。 綜上,python裏面的線程執行體就是真實的系統執行體

今天進一步研究下 python多線程/多進程機制 效率,不再闡述原理,一切‘坑’都產生於GIL機制, 直接上研究代碼了:

import time
from threading import Thread
import multiprocessing
 
COUNT = 50000000

def countdown(n):
    while n>0:
        n -= 1

start = time.time()
countdown(COUNT)
end = time.time()
print('Single-trd Time taken in seconds -', end - start)

t1 = Thread(target=countdown, args=(COUNT/2,))
t2 = Thread(target=countdown, args=(COUNT/2,))

start = time.time()
t1.start()
t2.start()
t1.join()
t2.join()
end = time.time()

print('Multi-trd Time taken in seconds -', end - start)


t1 = multiprocessing.Process(target=countdown, args=(COUNT/2,))
t2 = multiprocessing.Process(target=countdown, args=(COUNT/2,))

start = time.time()
t1.start()
t2.start()
t1.join()
t2.join()
end = time.time()

print('Multi-process Time taken in seconds -', end - start)

window平臺執行結果:

('Single-trd Time taken in seconds -', 1.5729999542236328)
('Multi-trd Time taken in seconds -', 4.871000051498413)
('Multi-process Time taken in seconds -', 6.109999895095825)

看到沒有,完全沒救了~~~

linux 平臺執行結果:

(Single-trd Time taken in seconds -', 2.1106820106506348)
('Multi-trd Time taken in seconds -', 2.712383985519409)
('Multi-process Time taken in seconds -', 1.1155731678009033)

linux還好,可以看到 首先,使用多進程(多主進程)是沒毛病,可以大大加快任務完成速度,多線程(子進程),還是慢一些,沒有起到應有的作用。

結論: python下是真線程和真進程,但應用其上愚蠢的GIL機制,僅在linux下使用多進程,纔可能得到 ‘併發’程序的好處。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章