Python對進程/線程鎖的一些理解

看multiprocessing部分的Python文檔,一點思考:
https://www.rddoc.com/doc/Python/3.6.0/zh/library/multiprocessing/#module-multiprocessing
離職啦,感覺一直拖拖拖,現(xiàn)在反而清醒輕松了不少,開始瘋狂產(chǎn)出吧~


from multiprocessing import Process, Lock

def f(l, i):
    l.acquire()
    try:
        print('hello world', i)
    finally:
        l.release()

if __name__ == '__main__':
    lock = Lock()

    for num in range(10):
        Process(target=f, args=(lock, num)).start()

這里給進程設置了一個進程鎖lock。lock在不同進程使用同一共享內存時,能夠確保線程之間互不影響,使用lock的方法是, 在每個線程/進程使用共享內存資源或修改共享內存之前,執(zhí)行l(wèi)ock.acquire()將共享內存上鎖, 確保當前進程執(zhí)行時,內存不會被其他進程訪問,執(zhí)行運算完畢后,使用lock.release()將鎖打開, 保證其他的線程可以使用該共享內存。
看似這樣做,進程就會輸出0-9了,但實際上并不會。

# output result
hello world 0
hello world 1
hello world 5
hello world 2
hello world 4
hello world 7
hello world 3
hello world 6
hello world 8
hello world 9

可見,第一個進程必然是0,這毫無疑問,但后面卻散亂排布。這與使用鎖的初衷相違背,這是為什么呢?
思考后發(fā)現(xiàn),在第一個進程執(zhí)行的過程中,即i=0時,它擁有當前的lock,因此它必然是先執(zhí)行的。但是由于進程是非阻塞的,因此在執(zhí)行Process的過程中,還是可以繼續(xù)迭代的,即num=1,2,...,9這個過程中他們都有可能進入Process這一步,等待num=0時執(zhí)行函數(shù)結束,獲得當前的Process,因此后面的順序是不可控的。
如果想要按順序排布,可以將進程設置為阻塞的。即當前進程執(zhí)行完之前,后面的進程會先掛起。這可以通過join()函數(shù)來實現(xiàn)。

# blocking
from multiprocessing import Process, Lock

def f(l, i):
    l.acquire()
    try:
        print('hello world', i)
    finally:
        l.release()

if __name__ == '__main__':
    lock = Lock()

    for num in range(10):
        p = Process(target=f, args=(lock, num))
        p.start()
        p.join()

輸出結果為:

# output result
hello world 0
hello world 1
hello world 2
hello world 3
hello world 4
hello world 5
hello world 6
hello world 7
hello world 8
hello world 9
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容