【问题标题】:How to send SIGINT to python running in a subprocess如何将 SIGINT 发送到在子进程中运行的 python
【发布时间】:2020-03-18 17:42:22
【问题描述】:

我有一个 python 程序,它在子进程中运行另一个 python 脚本(是的,我知道这种架构并不理想,但项目的性质使它成为必要)。我正在尝试:

1.向 python 子进程发送信号(模拟键盘击杀)

2。在子进程中捕获信号并在退出前执行一些清理

代码遵循以下一般模式:

A.py

import signal
import subprocess
import time

proc = subprocess.Popen('python B.py', shell=True)
time.sleep(1)
proc.send_signal(signal.SIGINT)

B.py

try:
  while True:
    # some application logic
    pass
except:
  # some cleanup logic
  print('bye')

但是当我运行 A.py 时,B.py 从来没有收到信号或者它是清理逻辑。知道这里发生了什么吗?

【问题讨论】:

  • 不,这个问题似乎与强制杀戮有关(信号 9)。我需要发送信号 2 并在子进程中捕获它
  • shell=True 表示chilld 进程是一个shell,而python 是孙子进程。 bugs.python.org/issue4855

标签: python linux subprocess


【解决方案1】:

不妨试试:

#!/usr/local/cpython-3.8/bin/python3

import signal
import subprocess
import time

proc = subprocess.Popen(['python3', 'B.py'], shell=False)
time.sleep(1)
proc.send_signal(signal.SIGINT)
proc.wait()

...作为你的 A.py?

我怀疑 shell 忽略了 SIGINT 而不是将其传递给 B.py。

【讨论】:

  • Shell 从不转发信号,所以这是正确的方法
【解决方案2】:

根据下面的评论,我启动了一个 Kubuntu 虚拟机,如果你指定要使用的 bashshell=False,它就可以工作。原因在评论中给出,但 /bin/sh 在 Debain/Ubuntu(可能还有其他发行版)上别名为 dash。要确定您的系统使用什么,请打开终端并输入ls -l /bin/sh

A.py

proc = subprocess.Popen(['/bin/bash', '-c', 'python3 B.py'], shell=False)

我使用python3 A.py 运行该文件。版本:Python 3.6.7。

之前的答案

它对我有用。我的想法是您可能需要在字符串中使用python3

我在 Arch Linux 上,python 实际上是 python3

这就是我所拥有的。

A.py

proc = subprocess.Popen('python B.py', shell=True)
time.sleep(1)
proc.send_signal(signal.SIGINT)

B.py

import time

try:
    while True:
        time.sleep(0.25)
        print('running B')
except KeyboardInterrupt:
    print('bye')

输出:

running B
running B
running B
bye

【讨论】:

  • 这适用于shbash 的系统,因为 bash 有一个尾调用优化,它试图避免在其最终命令上分叉。它会失败,例如Debian 其中shdash
  • 我更新了答案。并在 kubuntu 上进行了测试,它的 /bin/sh 别名为 dashThis also seems useful to know,虽然我不完全理解。
猜你喜欢
  • 2010-11-08
  • 1970-01-01
  • 2018-11-25
  • 1970-01-01
  • 2010-12-03
  • 1970-01-01
  • 1970-01-01
  • 2017-10-02
  • 2012-02-07
相关资源
最近更新 更多