成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

threading + multiprocessing + logging = 死鎖 ?

netmou / 910人閱讀

摘要:后來通過調(diào)查發(fā)現(xiàn)是因?yàn)槌绦蛑型瑫r(shí)使用了多線程,多進(jìn)程以及模塊,導(dǎo)致子進(jìn)程中出現(xiàn)了死鎖的情況。當(dāng)創(chuàng)建子進(jìn)程的時(shí)候,后臺(tái)線程中的模塊正好獲取了一個(gè)鎖在記錄日志信息。

前段時(shí)間有個(gè)程序突然出現(xiàn)了子進(jìn)程不工作的情況。

后來通過調(diào)查發(fā)現(xiàn)是因?yàn)槌绦蛑型瑫r(shí)使用了多線程,多進(jìn)程以及 logging 模塊,導(dǎo)致子進(jìn)程中出現(xiàn)了死鎖的情況。

當(dāng)創(chuàng)建子進(jìn)程的時(shí)候,后臺(tái)線程中的 logging 模塊正好獲取了一個(gè)鎖(threading.RLock)在記錄日志信息。由于在 unix/linux 平臺(tái)下 Python 是通過 fork 來創(chuàng)建子進(jìn)程的,因此創(chuàng)建子進(jìn)程的時(shí)候會(huì)把 logging 中的鎖也復(fù)制了一份,當(dāng)子進(jìn)程中需要記錄日志的時(shí)候發(fā)現(xiàn) logging 的鎖一直處于被占用的狀態(tài),從而出現(xiàn)了死鎖(復(fù)制的這個(gè)鎖永遠(yuǎn)也不會(huì)被釋放,因?yàn)樗乃姓呤歉高M(jìn)程的某個(gè)線程,但是這個(gè)線程釋放鎖的時(shí)候又不會(huì)影響子進(jìn)程里的這個(gè)鎖)。

復(fù)現(xiàn)問題的代碼如下:

import os
import sys
import threading
import time


class ThreadWorker(threading.Thread):
    def __init__(self):
        print("ThreadWorker: init")
        super().__init__()

    def run(self):
        print("ThreadWorker: running (rlock = {0})".format(global_rlock))

        global_rlock.acquire()
        print("ThreadWorker: i got lock {0}".format(global_rlock))
        time.sleep(5)
        global_rlock.release()
        print("ThreadWorker: release lock {0} and "
              "sleeping forever".format(global_rlock))

        time.sleep(600000)

global_rlock = threading.RLock(verbose=True)
worker = ThreadWorker()
worker.start()

time.sleep(1)
print("forking")
pid = os.fork()
if pid != 0:    # pid != 0 當(dāng)前處于父進(jìn)程
    print("parent: running (rlock = {0})".format(global_rlock))
else:      # pid = 0 當(dāng)前處于子進(jìn)程
    print("child: running (rlock = {0}), "
          "getting the lock...".format(global_rlock))
    global_rlock.acquire()
    print("child: got the lock {0}".format(global_rlock))
    sys.exit(0)

time.sleep(10)

上面代碼的執(zhí)行結(jié)果如下:

$ python fork.py
ThreadWorker: init
ThreadWorker: running (rlock = )
ThreadWorker: i got lock 
forking
parent: running (rlock = )
child: running (rlock = ), getting the lock...
ThreadWorker: release lock  and sleeping forever

從上面的結(jié)果中可以看出來:雖然線程隨后釋放了獲得的鎖,但是子進(jìn)程卻永遠(yuǎn)的卡在了獲取鎖的地方。

那么, 應(yīng)該如何解決這個(gè)問題呢?至少有三種解決辦法:

先創(chuàng)建子進(jìn)程,然后再創(chuàng)建線程:

import os
import sys
import threading
import time


class ThreadWorker(threading.Thread):
    def __init__(self):
        print("ThreadWorker: init")
        super().__init__()

    def run(self):
        print("ThreadWorker: running (rlock = {0})".format(global_rlock))

        global_rlock.acquire()
        print("ThreadWorker: i got lock {0}".format(global_rlock))
        time.sleep(5)
        global_rlock.release()
        print("ThreadWorker: release lock {0} and "
              "sleeping forever".format(global_rlock))

        time.sleep(600000)

global_rlock = threading.RLock(verbose=True)
worker = ThreadWorker()

print("forking")
pid = os.fork()
if pid != 0:    # pid != 0 當(dāng)前處于父進(jìn)程
    print("parent: running (rlock = {0})".format(global_rlock))
    worker.start()
else:      # pid = 0 當(dāng)前處于子進(jìn)程
    time.sleep(1)
    print("child: running (rlock = {0}), "
          "getting the lock...".format(global_rlock))
    global_rlock.acquire()
    print("child: got the lock {0}".format(global_rlock))
    global_rlock.release()
    print("child: release the lock {0}".format(global_rlock))
    sys.exit(0)

time.sleep(10)

結(jié)果:

$ python fork2.py
ThreadWorker: init
forking
parent: running (rlock = )
ThreadWorker: running (rlock = )
ThreadWorker: i got lock 
child: running (rlock = ), getting the lock...
child: got the lock 
child: release the lock 
ThreadWorker: release lock  and sleeping forever

可以看到子進(jìn)程和線程都能夠正常獲取鎖。

不要混合使用 threading, multiprocessing, logging/其他使用了線程鎖的模塊。 要么都是多線程,要么都是多進(jìn)程。

另一個(gè)辦法就是配置 logging 使用無鎖的 handler 來記錄日志信息。

參考資料

PythonLoggingThreadingMultiprocessingIntermixedStudy(Using modules Python logging, threading and multiprocessing in a single application.)

Issue 6721: Locks in the standard library should be sanitized on fork - Python tracker

multithreading - Deadlock with logging multiprocess/multithread python script - Stack Overflow

python - 使用multiprocessing.Process調(diào)用start方法后,有較小的幾率子進(jìn)程中run方法未執(zhí)行 - SegmentFault

python multiprocessing hanging, potential queue memory error? - Stack Overflow

Threads and fork(): think twice before mixing them. | Linux Programming Blog

原文地址: https://mozillazg.com/2016/09...

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/44210.html

相關(guān)文章

  • 「Python 面試」第三次更新

    摘要:說一下進(jìn)程線程以及多任務(wù)多進(jìn)程多線程和協(xié)程進(jìn)程概念一個(gè)程序?qū)?yīng)一個(gè)進(jìn)程,這個(gè)進(jìn)程被叫做主進(jìn)程,而一個(gè)主進(jìn)程下面還有許多子進(jìn)程。避免了由于系統(tǒng)在處理多進(jìn)程或者多線程時(shí),切換任務(wù)時(shí)需要的等待時(shí)間。 showImg(https://segmentfault.com/img/bVbuYxg?w=3484&h=2480); 閱讀本文大約需要 10 分鐘。 14.說一下進(jìn)程、線程、以及多任務(wù)(多進(jìn)...

    wslongchen 評(píng)論0 收藏0
  • Python_系統(tǒng)編程

    摘要:主進(jìn)程會(huì)等待所有的子進(jìn)程先結(jié)束,然后再結(jié)束主進(jìn)程。關(guān)閉進(jìn)程池,關(guān)閉后實(shí)例不再接收新的請(qǐng)求等待實(shí)例中的所有子進(jìn)程執(zhí)行完畢,主進(jìn)程才會(huì)退出,必須放在語句之后。主進(jìn)程一般都用來等待,任務(wù)在子進(jìn)程中執(zhí)行。 多任務(wù):同一個(gè)時(shí)間段中,執(zhí)行多個(gè)函數(shù)/運(yùn)行多個(gè)程序. 操作系統(tǒng)可以同時(shí)運(yùn)行多個(gè)任務(wù):操作系統(tǒng)輪流讓各個(gè)任務(wù)交替執(zhí)行,任務(wù)1執(zhí)行0.01秒,切換到任務(wù)2,任務(wù)2執(zhí)行0.01秒,再切換到任務(wù)3,...

    wuaiqiu 評(píng)論0 收藏0
  • Python多線程

    摘要:多線程的理解多進(jìn)程和多線程都可以執(zhí)行多個(gè)任務(wù),線程是進(jìn)程的一部分。多線程創(chuàng)建在中,同樣可以實(shí)現(xiàn)多線程,有兩個(gè)標(biāo)準(zhǔn)模塊和,不過我們主要使用更高級(jí)的模塊。多線程的應(yīng)用場(chǎng)景。 1、多線程的理解 多進(jìn)程和多線程都可以執(zhí)行多個(gè)任務(wù),線程是進(jìn)程的一部分。線程的特點(diǎn)是線程之間可以共享內(nèi)存和變量,資源消耗少(不過在Unix環(huán)境中,多進(jìn)程和多線程資源調(diào)度消耗差距不明顯,Unix調(diào)度較快),缺點(diǎn)是線程之間...

    dcr309duan 評(píng)論0 收藏0
  • python---線程

    摘要:某進(jìn)程內(nèi)的線程在其它進(jìn)程不可見。線程的實(shí)體包括程序數(shù)據(jù)和。包括以下信息線程狀態(tài)。當(dāng)線程不運(yùn)行時(shí),被保存的現(xiàn)場(chǎng)資源。用戶級(jí)線程執(zhí)行系統(tǒng)調(diào)用指令時(shí)將導(dǎo)致其所屬進(jìn)程被中斷,而內(nèi)核支持線程執(zhí)行系統(tǒng)調(diào)用指令時(shí),只導(dǎo)致該線程被中斷。線程能夠利用的表空 操作系統(tǒng)線程理論 線程概念的引入背景 進(jìn)程之前我們已經(jīng)了解了操作系統(tǒng)中進(jìn)程的概念,程序并不能單獨(dú)運(yùn)行,只有將程序裝載到內(nèi)存中,系統(tǒng)為它分配資源才能運(yùn)...

    Yangyang 評(píng)論0 收藏0
  • PyTips 0x 12 - Python 線程與協(xié)程(1)

    摘要:中關(guān)于線程的標(biāo)準(zhǔn)庫是,之前在版本中的在之后更名為,無論是還是都應(yīng)該盡量避免使用較為底層的而應(yīng)該使用。而與線程相比,協(xié)程尤其是結(jié)合事件循環(huán)無論在編程模型還是語法上,看起來都是非常友好的單線程同步過程。 項(xiàng)目地址:https://git.io/pytips 要說到線程(Thread)與協(xié)程(Coroutine)似乎總是需要從并行(Parallelism)與并發(fā)(Concurrency)談起...

    el09xccxy 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<