[英]Python script being stopped after a subprocess is completed
運行腳本時,我正在動態運行一組for循環。 基本上是調用項目列表,檢查要運行該項目的“階段”,然后按順序運行所有項目。 當我嘗試運行這些循環時,它將遍歷第一個對象,然后在終端中給出“ [1] + Stopped Script.py”。 我已經找到啟動腳本的方法,但是沒有關於如何完全避免這種情況的文章。
我已經嘗試使用Popen
, call
, check_output
等,他們都得到了相同的結果。 我確定這是我正在調用的另一項,但我認為關閉的其他程序不會殺死我的腳本,尤其是在子進程中不會終止。
我也嘗試過使用線程和多處理。 兩者均無濟於事。
def foo(list):
stages = 0
for c in things:
info = load_json_info(c)
if info["stage"] >= stages:
stages = info["stage"]
for p in list:
use_list(p)
stages = stages + 1
for i in range(stages):
for b in list:
info = load_json_info(b)
if info["stage"] == i:
if info["check"] != "NO":
output = call("command", shell=True)
if output == 0:
DO_THING()
else:
DONT_DO_THING()
else:
DONT_DO_THING()
它到達DO_THING()
並經歷所有這些過程,然后當需要調用另一個子DO_THING()
時,它再次消失。 不管該子DO_THING()
位於DO_THING()
還是我注釋掉所有內容,然后再次使其擊中output = call("command", shell=True)
行。 一旦再次使用子流程,它將停止。
人們發現有什么建議或方法可以阻止傳遞給我的腳本停止運行?
(僅提防您,我無權訪問導致腳本停止的"command"
的源,並且我正在使用的"command"
並不重要,因為我不能為此做任何事情。我也必須使用此"command"
。)
您看到的消息表明您的子進程正在停止 ,而不是有錯誤。 例如,在外殼程序中啟動進程后鍵入Ctrl-Z
時,或等效地,使用kill
命令向目標進程發送SIGTSTP
信號時,就會發生這種情況。 據推測,您無權訪問的command
正在接收該信號。 它甚至可以將其發送給自己,盡管在不了解更多有關命令的情況下,只是猜測如何發生或為什么發生。
您可以選擇使用signal
模塊(特別是pthread_sigmask()
函數pthread_sigmask()
在Python中忽略此信號。 一個指定信號屏蔽,以及如何處理它們。 在這種情況下,您要忽略SIGTSTP
信號,可通過執行以下操作: signal.pthread_sigmask(signal.SIG_BLOCK, (signal.SIGTSTP,))
。 (后一個參數實際上是要忽略的信號序列。)
運行此代碼段,您應該看到可以在終端中鍵入Ctrl-Z
,並且外殼程序應該顯示[1]+ Stopped ...
:
import time
duration = 5.0
print('Sleeping for {:0.2f} seconds'.format(duration))
time.sleep(duration)
但是,使用以下代碼,您將看到信號被忽略,並且無論信號如何,該過程將繼續“工作”(在這種情況下為睡眠)。 每當您按Ctrl-Z
時,您應該只在外殼上看到^Z
import time
import signal
duration = 5.0
print('Sleeping for {:0.2f} seconds, ignoring SIGTSTP'.format(duration))
signal.pthread_sigmask(signal.SIG_BLOCK, (signal.SIGTSTP,))
time.sleep(duration)
要在腳本中實際使用它,請在調用相關command
之前忽略信號。 優良作法是事先查詢進程的信號掩碼,並在使用command
完成后將其重置為該值。 您應該查看signal(3)
, sigprocmask(2)
和kill(2)
的手冊頁,以獲取有關信號和進程的更多信息。
為Python <= 2.7編輯
signal.pthread_sigmask
已在Python 3.3中添加。 適用於較早版本的解決方案是通過安裝處理該信號的處理程序來直接忽略該信號。 例如:
import signal
import time
duration = 5.0
signal.signal(signal.SIGTSTP, signal.SIG_IGN)
print 'Sleeping for %f seconds, ignoring SIGTSTP' % duration
time.sleep(duration)
與上面的3.3示例一樣,如果您Ctrl-Z
,您應該只看到^Z
Ctrl-Z
,這表明信號被忽略了。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.