最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python多進程并發(fā)與同步機制超詳細講解

 更新時間:2022年12月23日 08:42:44   作者:alwaysrun  
進程(Process),顧名思義,就是進行中的程序。有一句話說得好:程序是一個沒有生命的實體,只有處理器賦予程序生命時,它才能成為一個活動的實體。進程是資源分配的最小單元,也就是說每個進程都有其單獨的內(nèi)存空間

在《多線程與同步》中介紹了多線程及存在的問題,而通過使用多進程而非線程可有效地繞過全局解釋器鎖。 因此,通過multiprocessing模塊可充分地利用多核CPU的資源。

多進程

多進程是通過multiprocessing包來實現(xiàn)的,multiprocessing.Process對象(和多線程的threading.Thread類似)用來創(chuàng)建一個進程對象:

  • 在類UNIX平臺上,需要對每個Process對象調(diào)用join()方法 (實際上等同于wait)避免其成為僵尸進程。
  • multiprocessing提供了threading包中沒有的IPC(比如Pipe和Queue),效率上更高。應(yīng)優(yōu)先考慮Pipe和Queue,避免使用Lock/Event/Semaphore/Condition等同步方式。
  • 多進程應(yīng)盡量避免共享資源。必要時可以通過共享內(nèi)存和Manager的方法來共享資源。

僵尸進程

在unix或unix-like系統(tǒng)中,當一個子進程退出后,它就會變成一個僵尸進程,如果父進程沒有通過wait系統(tǒng)調(diào)用來讀取這個子進程的退出狀態(tài)的話,這個子進程就會一直維持僵尸進程狀態(tài)(占據(jù)部分系統(tǒng)資源,無法釋放)。

要清除僵尸進程,有:

結(jié)束父進程(一般是主進程):當父進程退出的時候僵尸進程也會被隨之清除。

讀取子進程退出狀態(tài):如通過multiprocessing.Process產(chǎn)出的進程可以:

  • 調(diào)用join()來等待子進程的方法來(內(nèi)部會wait子進程);
  • 在父進程中處理SIGCHLD信號:在處理程序中調(diào)用wait系統(tǒng)調(diào)用或者直接設(shè)置為SIG_IGN來清除僵尸進程;

把進程變成孤兒進程,這樣進程就會自動交由init進程來自動處理。

通過設(shè)定signal.signal(signal.SIGCHLD, signal.SIG_IGN)或join進程可避免僵尸進程的產(chǎn)生

def zombieProc():
    print("zombie running")
    time.sleep(5)
    print("zombie exit")
if __name__ == '__main__':
    signal.signal(signal.SIGCHLD, signal.SIG_IGN)
    proc = multiprocessing.Process(target=zombieProc)
    proc.start()
    # proc.join()
    time.sleep(30)

Process類

Process([group [, target [, name [, args [, kwargs]]]]]),實例化得到的對象,表示一個子進程任務(wù):

  • group參數(shù)未使用,值始終為None;
  • target表示調(diào)用對象,即子進程要執(zhí)行的任務(wù);
  • args表示調(diào)用對象的位置參數(shù)元組,args=(1, ‘test’, [‘one’]);
  • kwargs表示調(diào)用對象的字典參數(shù),kwargs={‘name’:‘mike’,‘age’:18};
  • name為子進程的名稱;

Process類的屬性與方法:

  • start():啟動進程,并執(zhí)行其run方法;
  • run():進程啟動時運行的方法,繼承Process類時必須要實現(xiàn)方法;
  • terminate():強制終止進程,不會進行任何清理操作(若p創(chuàng)建了子進程,則子進程就成了僵尸進程);如進程還持有鎖等,那么也不會被釋放,進而導致死鎖;
  • is_alive():返回進程是否在運行狀態(tài);
  • join([timeout]):等待進程終止;
  • daemon:默認值為False,如果設(shè)為True,代表為守護進程(當父進程終止時,隨之終止;并且不能創(chuàng)建自己的新進程),必須在start()之前設(shè)置;
  • name:進程的名稱;
  • pid/ident:進程的pid;
  • exitcode:進程在運行時為None、如果為–N,表示被信號N結(jié)束;
  • authkey:進程的身份驗證碼(默認是由os.urandom()隨機生成的32字符的字符串),在涉及網(wǎng)絡(luò)連接的底層進程間通信時提供安全性;

也可通過os.getpid()獲取進程的PID,os.getppid()獲取父進程的PID。

函數(shù)方式

通過Process類直接運行函數(shù):

def simpleRoutine(name, delay):
    print(f"routine {name} starting...")
    time.sleep(delay)
    print(f"routine {name} finished")
if __name__ == '__main__':
    thrOne = multiprocessing.Process(target=simpleRoutine, args=("First", 1))
    thrTwo = multiprocessing.Process(target=simpleRoutine, args=("Two", 2))
    thrOne.start()
    thrTwo.start()
    thrOne.join()
    thrTwo.join()

繼承方式

通過繼承Process類,并實現(xiàn)run方法來啟動進程:

class SimpleProcess(multiprocessing.Process):
    def __init__(self, name, delay):
        super().__init__()
        self.name = name
        self.delay = delay
    def run(self):
        print(f"Process {self.name} starting...")
        time.sleep(self.delay)
        print(f"Process {self.name} finished")
if __name__ == '__main__':
    thrOne = SimpleProcess("First", 2)
    thrTwo = SimpleProcess("Second", 1)
    thrOne.start()
    thrTwo.start()
    thrOne.join()
    thrTwo.join()

同步機制

進程間同步與線程間同步類似(只是所有對象都在multiprocessing模塊中):

  • Lock/Rlock: 通過acquire()和release()來獲取與釋放鎖;
  • Event: 事件信號,通過set()和clear()來設(shè)定與清楚信號;通過wait()來等待信號;
  • Condition: 條件變量;通過wait()用來等待條件,通過notify/notify_all()來通知等待此條件的進程(等待與通知前,都需先持有鎖);
  • Semaphore: 信號量;維護一個計數(shù)器;
  • Barrier: 屏障;只有等待進程數(shù)量達到要求數(shù)量,才會同時開始執(zhí)行屏障保護后的代碼。

屏障示例:

def waitBarrier(name, barr: multiprocessing.Barrier):
    print(f"{name} waiting for open")
    try:
        barr.wait()
        print(f"{name} running")
        time.sleep(2)
    except multiprocessing.BrokenBarrierError:
        print(f"{name} exception")
    print(f"{name} finished")
def openFun():  # 屏障滿足條件時,執(zhí)行一次
    print("barrier opened")
if __name__ == '__main__':
    signal = multiprocessing.Barrier(5, openFun)
    for i in range(10):
        multiprocessing.Process(target=waitBarrier, args=(i, signal)).start()  
        time.sleep(1)  

當?shù)?個進程啟動時,前面5個進程會同時開始執(zhí)行(openFun函數(shù)會執(zhí)行一次);當?shù)?0個進程啟動時,后面5個進程會同時開始執(zhí)行一次(openFun函數(shù)又會執(zhí)行一次)。

狀態(tài)管理Managers

Managers提供了一種創(chuàng)建由多進程(包括跨機器間進程共享)共享的數(shù)據(jù)的方式:

  • multiprocessing.Manager()返回一個SyncManager對象;此對象對應(yīng)著一個管理者子進程(manager process)以及代理(其他子進程使用);
  • 它確保當某一進程修改了共享對象之后,其他進程中的共享對象也會得到更新;
  • 其支持的類型有:list、dict、Namespace、Lock、RLock、Semaphore、BoundedSemaphore、Condition、Event、Queue、Value和Array。

多進程進共享字典與列表(每個進程中都能看到其他進程修改過的內(nèi)容)

def worker(dictContext: dict, lstContext: list, name):
    pid = os.getpid()
    dictContext[name] = pid
    lstContext.append(pid)
    print(f"{name} worker: {lstContext}")
def managerContext():
    mgr = multiprocessing.Manager()
    multiprocessing.managers
    dictContext = mgr.dict()
    lstContext = mgr.list()
    jobs = [multiprocessing.Process(target=worker, args=(dictContext, lstContext, i)) for i in range(10)]
    for j in jobs:
        j.start()
    for j in jobs:
        j.join()
    print('Results:', dictContext)

到此這篇關(guān)于Python多進程并發(fā)與同步機制超詳細講解的文章就介紹到這了,更多相關(guān)Python多進程并發(fā)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • python 將大文件切分為多個小文件的實例

    python 將大文件切分為多個小文件的實例

    今天小編就為大家分享一篇python 將大文件切分為多個小文件的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-01-01
  • Python OpenCV圖像指定區(qū)域裁剪的實現(xiàn)

    Python OpenCV圖像指定區(qū)域裁剪的實現(xiàn)

    這篇文章主要介紹了Python OpenCV圖像指定區(qū)域裁剪的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-10-10
  • Python數(shù)據(jù)讀寫之Python讀寫CSV文件

    Python數(shù)據(jù)讀寫之Python讀寫CSV文件

    這篇文章主要介紹了Python數(shù)據(jù)讀寫之Python讀寫CSV文件,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,感興趣的小伙伴可以參考一下
    2022-06-06
  • 最新評論

    井冈山市| 罗平县| 东莞市| 永康市| 闽侯县| 忻城县| 疏勒县| 运城市| 昔阳县| 咸宁市| 视频| 包头市| 通榆县| 翼城县| 沙河市| 乐陵市| 新乡市| 民和| 岫岩| 伊通| 祁阳县| 平阳县| 绿春县| 大英县| 海伦市| 玛沁县| 临朐县| 股票| 灵武市| 广南县| 太原市| 平塘县| 衡水市| 平阴县| 巴塘县| 伊通| 康平县| 清远市| 大理市| 游戏| 龙海市|