簡體   English   中英

Python:如何防止子進程接收 CTRL-C / Control-C / SIGINT

[英]Python: How to prevent subprocesses from receiving CTRL-C / Control-C / SIGINT

我目前正在為在 shell 中運行的專用服務器開發包裝器。 包裝器通過子進程生成服務器進程,並觀察其輸出並對其做出反應。

專用服務器必須明確給出命令以正常關閉。 因此,CTRL-C 不能到達服務器進程。

如果我在 python 中捕獲 KeyboardInterrupt 異常或覆蓋 SIGINT 處理程序,服務器進程仍會收到 CTRL-C 並立即停止。

所以我的問題是:如何防止子進程接收 CTRL-C / Control-C / SIGINT?

#python IRC-Channel (Freenode) 中的某個人通過指出subprocess.Popen (...)preexec_fn參數來幫助我:

如果preexec_fn設置為可調用對象,則該對象將在子進程執行之前在子進程中調用。 (僅限 Unix)

因此,以下代碼解決了該問題(僅限 UNIX):

import subprocess
import signal

def preexec_function():
    # Ignore the SIGINT signal by setting the handler to the standard
    # signal handler SIG_IGN.
    signal.signal(signal.SIGINT, signal.SIG_IGN)

my_process = subprocess.Popen(
    ["my_executable"],
    preexec_fn = preexec_function
)

注意:實際上並沒有阻止信號到達子進程。 相反,上面的preexec_fn 會覆蓋信號的默認處理程序,從而忽略信號。 因此,如果子進程再次覆蓋SIGINT處理程序,則此解決方案可能不起作用。

另一個注意事項:此解決方案適用於各種子進程,即它不僅限於用 Python 編寫的子進程。 例如,我正在為其編寫包裝器的專用服務器實際上是用 Java 編寫的。

結合其他一些可以解決問題的答案 - 發送到主應用程序的信號不會被轉發到子進程。

import os
from subprocess import Popen

def preexec(): # Don't forward signals.
    os.setpgrp()

Popen('whatever', preexec_fn = preexec)

你可以做這樣的事情,使其在 windows 和 unix 中工作:

import subprocess
import sys

def pre_exec():
    # To ignore CTRL+C signal in the new process
    signal.signal(signal.SIGINT, signal.SIG_IGN)

if sys.platform.startswith('win'):
    #https://msdn.microsoft.com/en-us/library/windows/desktop/ms684863(v=vs.85).aspx
    #CREATE_NEW_PROCESS_GROUP=0x00000200 -> If this flag is specified, CTRL+C signals will be disabled
    my_sub_process=subprocess.Popen(["executable"], creationflags=0x00000200)
else:
    my_sub_process=subprocess.Popen(["executable"], preexec_fn = pre_exec)

嘗試在生成子進程之前將 SIGINT 設置為被忽略(之后將其重置為默認行為)。

如果這不起作用,您將需要閱讀作業控制並學習如何將進程放在其自己的后台進程組中,以便^C甚至不會導致內核在第一名。 (如果不編寫 C 幫助程序,在 Python 中可能無法實現。)

另請參閱這個較舊的問題

經過一個小時的各種嘗試,這對我有用:

process = subprocess.Popen(["someprocess"], creationflags=subprocess.DETACHED_PROCESS | subprocess.CREATE_NEW_PROCESS_GROUP)

這是windows的解決方案。

暫無
暫無

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

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