【问题标题】:kill process do not kill the subprocess and do not close a terminal window杀死进程不要杀死子进程并且不要关闭终端窗口
【发布时间】:2021-07-24 16:07:39
【问题描述】:

我正在开发 UBUNTU,我有一个文件 main.py,里面有一个代码:

#!/usr/bin/env python3
# coding=utf-8
import os
import time
from subprocess import Popen, PIPE, call, signal

base_path = os.path.abspath('')
path_to_file = base_path + '/test_subprocess.py'
p = Popen(['gnome-terminal', "--",  path_to_file])
time.sleep(2)

os.kill(p.pid, signal.SIGKILL)

我有 test_subprocess.py 的代码如下:

#!/usr/bin/env python3
# coding=utf-8

import time

def print_message():
    while True:
        print('I am working!')
        time.sleep(0.5)
    
print_message()

我试图杀死子进程,但之后

os.kill(p.pid, signal.SIGKILL)

子进程仍在工作并打印'I am working!'

如何完成子进程以及如何关闭 gnome 终端? 如果我选择了完全错误的方式。你能告诉我工作的例子吗?

新版test_subprocess.py

#!/usr/bin/env python3
# coding=utf-8
import sys
from subprocess import signal
import time

def print_message():
    while True:
        print('I am working!')
        time.sleep(0.5)
        if signal.SIGKILL:  # it is braking a loop when parent process terminate!
            print('I am killing self!')
            break

print_message()

我应该像上面那样做吗?

【问题讨论】:

  • test_subprocess.py 中的 signal.SIGKILL 能解决我的问题吗?我已经检查过了,它正在关闭子进程。这就是我所需要的吗?
  • 请不要在问题中添加额外的问题(和答案)。每个问题页面应该是关于一个问题。更改/添加您的问题可能会使现有答案无效 - 请避免这种情况。有新问题可以ask another one

标签: python subprocess popen gnome-terminal


【解决方案1】:

您可以尝试以下方法:

p = Popen(['gnome-terminal', "--",  path_to_file])
PIDs = p.pid
os.system("kill {0}".format(PIDs))

Popen.pid 子进程的进程ID。

注意,如果你将shell参数设置为True,这就是进程 生成的 shell 的 ID。

http://docs.python.org/library/subprocess.html

这至少会杀死正确的进程。不确定它是否会关闭终端。

编辑:杀死进程关闭终端:

p = Popen(['gnome-terminal', '--disable-factory', '-e', path_to_file], preexec_fn=os.setpgrp)

os.killpg(p.pid, signal.SIGINT)

感谢https://stackoverflow.com/a/34690644/15793575,我为你的命令修改了:

  • --disable-factory 用于避免重复使用活动终端,以便我们可以通过子进程句柄杀死新创建的终端
  • os.setpgrp 将 gnome-terminal 放在它自己的进程组中,这样 os.killpg() 可用于向该组发送信号

【讨论】:

  • 这个:p = Popen(['gnome-terminal', '--disable-factory', '-e', path_to_file], preexec_fn=os.setpgrp) os.killpg(p.pid , signal.SIGINT) 为我工作。但是如果在子进程中你必须在关闭之前做一些事情怎么办?例如,如果您有打开的文件,或者您必须在关闭程序之前保存您的工作?
  • 如何在 VENV 中将 Python 脚本作为子进程运行?
  • 我在子进程的 os.environ 中找到了答案。如果我在 env 中调用父级,则在 env 中调用子级。
【解决方案2】:

Popen.pid
子进程的进程ID。

注意,如果你把shell参数设置为True,就是这个过程 生成的 shell 的 ID。

尝试将Popen 构造函数的shell 参数设置为False。 (p = Popen(['gnome-terminal', "--", path_to_file]) -> p = Popen(['gnome-terminal', "--", path_to_file], shell=False))。不久前我遇到了类似的问题 - 这为我解决了问题。

【讨论】:

  • 你好。我用 shell=False 进行了测试,但对我没有帮助。父程序完成后,子程序仍在工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-08-09
  • 1970-01-01
  • 1970-01-01
  • 2018-10-14
  • 1970-01-01
  • 1970-01-01
  • 2010-12-08
相关资源
最近更新 更多