python學習筆記 - 對進程的管理 Lock、Semaphore、Event

前面的文章介紹瞭如何進行進程間的通訊方式。結下來咱們來說一講如何管理多個進程對資源的訪問。
例若有時候咱們多個進程對某一個文件進行寫入的時候,若是咱們一個進程尚未寫完,就被CPU切換到另外一個進程,勢必會形成文件寫入的順序亂七八糟的。正確的狀況是,在一個進程寫完的時候,再讓另外一個進程進行寫入。這時候,咱們須要一個鎖。windows

Lock

Lock有一點像咱們平常生活中上廁所。廁所就是咱們的資源,能夠解決咱們的需求。可是廁所是有限的,並且一次只能進去一我的。同時想上廁所的人不少,還沒輪到的人所有在外邊等待,輪到的人能夠進去使用廁所,同時會鎖上門,禁止其餘人進入。上完廁所的人出來,打開廁所門,讓後面的人進來。
翻譯成計算機語言就是:
這個資源只容許一個Process訪問,所以只有一個門,上一把鎖。
圖片描述app

from multiprocessing import Lock, Pool
import random


def write_file(lock):
    with lock:
        with open('write_demo.txt', 'a') as wf:
            wf.write(str(random.random())+"\r")


if __name__ == '__main__':
    lock = Lock()
    pool = Pool()
    for i in range(0, 10):
        pool.apply_async(write_file(lock))
    pool.close()

注意: lock其實跟文件的打開關閉同樣,可使用with語句。dom

Lock supports the context manager protocol and thus may be used in with statements.

解釋一下這裏爲何是with lock:由於在if __name__ == '__main__':中咱們已經建立了Lock對象。而with後是須要跟一個對象,所以直接將lock寫在後面便可。那麼with後的代碼塊都是被with所保護。
若是不用with語句的話,則須要手動寫:async

lock.acquire()
lock.release()

二者之間的代碼纔是被鎖保護的。ui

RLock

RLock是Lock的遞歸版。啥意思呢?
咱們知道lock.aquire()是請求鎖,噹噹前的鎖事鎖定狀態的時候,則lock.aquire()則會阻塞等待鎖釋放。
所以若是咱們寫了兩個lock.aquire()則會產生死鎖。第二個lock.aquire()會永遠等待在那裏。spa

使用RLock則不會有這種狀況。RLock一個門支持多個鎖,上多少把鎖,就得釋放多少次。
圖片描述翻譯

Semaphore

Semaphore有信號燈的意思。
Semaphore跟Lock相似,可是Semaphore能夠容許指定最多多少個進程訪問資源。
就像該資源有多個門,每一個門一把鎖。一個進程訪問了資源,鎖了門,還有其餘門可使用。可是若是全部門都被使用了,那麼就得等待有進程出來釋放鎖才能夠。
圖片描述
在編寫Sempaphore示例代碼的時候,遇到了一個比較奇怪的問題。unix

from multiprocessing import Semaphore, Pool
import os
import time


def worker_process(s):
    print id(s)
    with s:
        print "Process (%s) run" % os.getpid()
        time.sleep(1)
        print "Process (%s) ended" % os.getpid()


if __name__ == '__main__':
    semaphore = Semaphore(1)
    print id(semaphore)
    pool = Pool(4)
    for i in range(0, 1000):
        pool.apply_async(worker_process, args=(semaphore,))
    pool.close()
    pool.join()
    print "Main Process ended"

如上所示的代碼,傳遞semaphore時候,worker_process並不會執行。
可是若是將semaphore定義成一個全局變量,那麼則能夠在Linux或者unix下執行。(懷疑會在windows下出錯)code

from multiprocessing import Semaphore, Pool
import os
import time

semaphore = Semaphore(1)


def worker_process():
    print id(semaphore)
    with semaphore:
        print "Process (%s) run" % os.getpid()
        time.sleep(1)
        print "Process (%s) ended" % os.getpid()


if __name__ == '__main__':
    print id(semaphore)
    pool = Pool(4)
    for i in range(0, 1000):
        pool.apply_async(worker_process)
    pool.close()
    pool.join()
    print "Main Process ended"

以上代碼能夠正確執行。
暫時不知道問題出在哪裏?有會的網友還請指點。對象

Event

還有Event。Event也是用於進程間的通訊,那麼它跟Queue、Pipe有什麼區別呢?

其實Python多進程還有許多的內容。在後續的文章中介紹。

相關文章
相關標籤/搜索