【问题标题】:Python 3 Stopping subprocess by sending Ctrl CPython 3 通过发送 Ctrl C 停止子进程
【发布时间】:2019-12-27 16:51:44
【问题描述】:

我有一些 GPU 测试软件正在尝试使用 python3 自动化,测试通常会运行 3 分钟,然后由用户使用 ctrl+c 取消,生成以下输出

使用 ctrl+c 退出后,可以再次运行测试,没有问题

当尝试使用子进程 popen 自动执行此操作并发送 SIGINT 或 SIGTERM 时,我得到的结果与使用键盘输入时不同。脚本突然退出,在随后的运行中找不到 gpus(假设它没有正确卸载驱动程序)

from subprocess import Popen, PIPE
from signal import SIGINT
from time import time


def check_subproc_alive(subproc):
    return subproc.poll() is None

def print_subproc(subproc, timer=True):
    start_time = time()
    while check_subproc_alive(subproc):
        line = subproc.stdout.readline().decode('utf-8')
        print(line, end="")
        if timer and (time() - start_time) > 10:
            break


subproc = Popen(['./gpu_test.sh', '-t', '1'], stdin=PIPE, stdout=PIPE, stderr=PIPE, shell=False)

print_subproc(subproc)

subproc.send_signal(SIGINT)

print_subproc(subproc, False)

如何像用户键入一样将 ctrl+c 发送到子进程?

**更新

import subprocess


def start(executable_file):
    return subprocess.Popen(
        executable_file,
        stdin=subprocess.PIPE,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE
    )


def read(process):
    return process.stdout.readline().decode("utf-8").strip()


def write(process):
    process.stdin.write('\x03'.encode())
    process.stdin.flush()

def terminate(process):
    process.stdin.close()
    process.terminate()
    process.wait(timeout=0.2)


process = start("./test.sh")
write(process)
for x in range(100):
    print(read(process))
terminate(process)

尝试了上面的代码,可以让字符注册到虚拟 sh 脚本,但是发送 \x03 命令只会发送一个空字符并且不会结束脚本

【问题讨论】:

  • 请发布您的代码。
  • 不是真正的重复,那是使用 pyserial 而不是子进程模块

标签: python python-3.x linux gpu


【解决方案1】:

我认为您可能可以使用这样的东西:

import signal
try:
    p=subprocess...
except KeyboardInterrupt:
    p.send_signal(signal.SIGINT)

【讨论】:

  • 如果在子进程执行期间发生键盘中断,这是否会发送 SIGINT?我试图首先自动化发生的键盘中断
  • 如果你想在不按ctrl+c的情况下发送sigint,你可以直接使用p.send_signal(signal.SIGINT)而不用尝试,除了block
  • 这就是我想要做的,但发送 SIGINT 与我运行 gpu 测试脚本并手动按 ctrl+c 时不同。手动按 ctrl+c 会导致脚本报告错误手动用户干预并正常停止。发送 SIGINT 使脚本停止而无需拆卸
  • 我认为是因为你有 shell=False,你可以试试没有那个吗?
  • 如果我将 shell 设置为 true,则必须在执行下一行代码之前完成 gpu 测试
【解决方案2】:

以下解决方案是我能找到的唯一适用于 windows 并且与发送 Ctrl+C 事件最相似的解决方案。

import signal
os.kill(self.p.pid, signal.CTRL_C_EVENT)

【讨论】:

  • 这与self.p.send_signal(signal.CTRL_C_EVENT) 几乎相同。在这种情况下,检查进程是否“已经死亡”。
猜你喜欢
  • 1970-01-01
  • 2015-04-07
  • 2017-10-02
  • 1970-01-01
  • 1970-01-01
  • 2019-03-17
  • 2013-08-21
  • 1970-01-01
  • 2014-05-29
相关资源
最近更新 更多