簡體   English   中英

subprocess.wait() 不等待 Popen 進程完成(使用線程時)?

[英]subprocess.wait() not waiting for Popen process to finish (when using threads)?

在使用subprocess.Popen()從我的 python 腳本中使用線程讓它們同時運行時,我遇到了一些問題。 在每個線程中,我使用popen()調用運行應用程序,然后通過調用wait()等待它完成。 問題似乎是wait()調用實際上並沒有等待進程完成。 我嘗試只使用一個線程,並在進程開始和結束時打印出文本消息。 所以線程 function 看起來像這樣:

def worker():
    while True:
        job = q.get() # q is a global Queue of jobs
        print('Starting process %d' % job['id'])
        proc = subprocess.Popen(job['cmd'], shell=True)
        proc.wait()
        print('Finished process %d' % job['id'])
        job.task_done()

但即使我只使用一個線程,它也會在出現任何“已完成進程...”消息之前打印出幾條“正在啟動進程...”消息。 是否存在wait()實際上不等待的情況? 我有幾個不同的外部應用程序(C++ 控制台應用程序),它們又會同時運行多個實例,對於其中一些,我的代碼可以工作,但對於其他一些則不行。 外部應用程序是否存在某些問題會以某種方式影響對wait()的調用? 創建線程的代碼如下所示:

for i in range(1):
    t = Thread(target=worker)
    t.daemon = True
    t.start()
q.join() # Wait for the queue to empty

更新 1 :我還應該補充一點,對於某些外部應用程序,我有時會得到 -1073471801 的返回碼 ( proc.returncode )。 例如,其中一個外部應用程序將在前兩次調用Popen時給出該返回碼,但不是最后兩次(當我有四個作業時)。

更新 2 :為了解決問題,現在我在隊列中有四個作業,它們是四個不同的測試用例。 當我運行我的代碼時,對於其中一個外部應用程序,前兩個Popen調用會生成返回碼 -1073471801。 但是,如果我打印Popen調用的確切命令,並在命令 window 中運行它,它就會毫無問題地執行。

解決了! 我設法解決了我遇到的問題。 我認為問題在於我缺乏線程編程方面的經驗。 我錯過了這樣一個事實,即當我創建我的第一個工作線程時,它們會繼續存在,直到 python 腳本退出。 每次我將新項目放入隊列時,我都會錯誤地創建更多工作線程(我為每個要運行的外部程序分批執行此操作)。 所以當我到達第四個外部應用程序時,我有四個線程同時運行,盡管我只以為我有一個。

您也可以使用check_call()代替 Popen。 check_call()等待命令完成,即使shell=True然后返回作業的退出代碼。

遺憾的是,當使用shell=True運行子進程時, wait( )只會等待sh子進程完成,而不是等待命令cmd

我會建議是否可以不使用shell=True ,如果不可能,您可以像在這個答案中那樣創建一個進程組並使用os.waitpid來等待進程組,而不僅僅是 shell 進程。

希望這有幫助:)

我也遇到了問題,但受到了你的啟發。

我的看起來像這樣,並且工作得很好:

    startupinfo = subprocess.STARTUPINFO()
    startupinfo.dwFlags = subprocess.STARTF_USESHOWWINDOW
    startupinfo.wShowWindow = subprocess.SW_HIDE
    proc = subprocess.Popen(command, startupinfo=startupinfo)
    proc.communicate()
    proc.wait()

請注意,這個也隱藏了 window。

確保您調用的所有應用程序在完成時都具有有效的系統返回碼

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM