Python調(diào)用exe程序的注意事項(xiàng)

  • 實(shí)際應(yīng)用場(chǎng)景:某應(yīng)用使用Python實(shí)現(xiàn)了某算法,其中Python會(huì)調(diào)用一個(gè)demo.exe。根據(jù)不同的輸入數(shù)據(jù),demo.exe運(yùn)行時(shí)間有長有短,短的10s內(nèi),長的10+分鐘

問題:

  1. Python算法是由后臺(tái)API(Java)調(diào)用的,有實(shí)時(shí)性要求(比如1分鐘內(nèi)出結(jié)果)
  2. demo.exe運(yùn)行時(shí)特別耗資源(CPU和內(nèi)存),因此同時(shí)運(yùn)行的demo.exe不能太多,否則導(dǎo)致電腦卡死

思路:

想辦法設(shè)置一個(gè)超時(shí)時(shí)間,如果超時(shí)時(shí)間內(nèi)能夠分析完畢,返回分析結(jié)果;如果timeout了,殺死demo.exe進(jìn)程,返回一個(gè)默認(rèn)的結(jié)果。

嘗試過的解決辦法 - 多線程

多線程中使用os.system()運(yùn)行demo.exe,線程設(shè)置守護(hù)線程為True,入口函數(shù)threadTest()啟動(dòng)新線程后,time.sleep(10)一個(gè)固定時(shí)間,比如10s,然后判斷保存結(jié)果的隊(duì)列threadQueue中有沒有數(shù)據(jù),如果沒有數(shù)據(jù),使用os.system('taskkill /F /IM demo.exe')殺死進(jìn)程

def run_demo_exe():
    ...

def threadTest():
    # 線程
    openposeThread = threading.Thread(target=run_demo_exe)
    openposeThread.setDaemon(True)
    openposeThread.start()

    time.sleep(10)
    if threadQueue.empty():
        os.system('taskkill /F /IM demo.exe')
        return RESULT_DIC['NO_PERSON']
    else:
        return threadQueue.get()

問題

os.system('taskkill /F /IM demo.exe')會(huì)殺死所有名字是demo.exe的進(jìn)程,也就是其它任務(wù)的進(jìn)程也會(huì)被殺死

嘗試過的解決辦法 - 多進(jìn)程

思路跟使用多線程的思路一樣,只不過想通過kill子進(jìn)程實(shí)現(xiàn)kill任務(wù)對(duì)應(yīng)的demo.exe進(jìn)程,而不影響其它任務(wù)的demo.exe進(jìn)程

def threadTest():
    # 進(jìn)程
    p = multiprocessing.Process(target=run_demo_exe)
    p.daemon = True
    p.start()
    time.sleep(10)
    if threadQueue.empty():
        p.terminate()
        return RESULT_DIC['NO_PERSON']
    else:
        return threadQueue.get()

問題

實(shí)測(cè)后發(fā)現(xiàn),kill子進(jìn)程后,當(dāng)前任務(wù)對(duì)應(yīng)的demo.exe進(jìn)程會(huì)繼續(xù)運(yùn)行下去

最終的解決辦法 - subprocess.Popen

使用subprocess.Popen取代os.system()運(yùn)行demo.exe,subprocess.Popen會(huì)返回一個(gè)對(duì)象,該對(duì)象可以設(shè)置超時(shí)時(shí)間,timeout之后可以調(diào)用該對(duì)象的kill()直接殺死當(dāng)前任務(wù)對(duì)應(yīng)的demo.exe進(jìn)程,而不影響其它任務(wù)的進(jìn)程

def run_demo_exe():
    myPopenObj = subprocess.Popen("D:/demo/OpenPoseDemo.exe")
    try:
        myPopenObj.wait(timeout=SECONDS_TIMEOUT)
    except Exception as e:
        print("===== process timeout ======")
        myPopenObj.kill()
        return None
    ...
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容