【问题标题】:process.pid in python giving wrong value on macOS mojavepython中的process.pid在macOS mojave上给出错误的值
【发布时间】:2019-09-21 13:06:29
【问题描述】:

我已经尝试了至少十几种不同的 python 脚本来杀死这里显示的子进程,包括

thisthis

但我非常沮丧。

这里是蟒蛇:

import subprocess, os
import time,signal,psutil
process = subprocess.Popen(['open', '/Applications/Preview.app', 'images/conv1.jpg'], shell=False)
print (process.pid)
time.sleep(2)
print (process.pid)
os.kill(process.pid, signal.SIGKILL)

进程 id 打印在终端中,预览开始并打开图像,进程 id 再次打印,python 终止,我回到 shell 提示符 - 但预览和图像仍然打开。当我在“活动监视器”中检查进程 id 时,结果是 preview.app 的 ACTUAL 进程 id 比值 process.pid 大一。

我必须把最后一行改成这样:

os.kill(process.pid+1, signal.SIGKILL)

它有效。为什么????

【问题讨论】:

  • 如果我去掉最后一行以便预览不会终止并且还注释掉 time.sleep(2),那么实际进程 ID 比打印的值大 5。这是什么怪事?
  • 你确定它不是由其他东西启动的吗?另外,您的第一个链接使用的是os.killpg,而不是os.kill

标签: python macos subprocess


【解决方案1】:

简单地执行process.pid + 1 不会杀死该进程,只是碰巧在那个时候你的孩子从它的父母那里分叉,没有其他进程启动。
你的process.pid不是你图片conv1.jpg的实际pid。所以我们需要找到它的真实pid:

import subprocess
import os
import time
import signal
process = subprocess.Popen(['xdg-open', 'stroke.png'])#I have linux machine and stroke.png is a file which I need to open.
print(process.pid)
time.sleep(5)
print(process.pid)
a = subprocess.Popen(['ps', '-eo', 'pid,ppid,command'], stdout = subprocess.PIPE)
b = subprocess.Popen(['grep', 'stroke.png'], stdin = a.stdout, stdout = subprocess.PIPE)

output, error  = b.communicate()
output = output.decode("utf-8").split('\n')
pid = ''
pid = int(pid.join(list(output[0])[1:5]))
print(pid)
os.kill(pid, signal.SIGKILL)

这里我们要做的是我们采用两个进程ab
a 给出了所有的 pid,所以我们需要为我们的文件过滤掉 pid,在我的情况下是 stroke.png 在进程中b 使用 grep。
我们将 a 的标准输出分配给 b 的 stin,然后将 b 的标准输出分配给 output
我们需要将output 解码为 utf-8,因为它以字节形式返回,而我们需要它以字符串形式。

print(output)

给我们以下结果:

[' 7990  1520 eog /home/rahul/stroke.png', ' 8004  7980 grep stroke.png', '']

所以我们需要数字7990,它是我们stroke.png的真正pid。
这是通过使用int(pid.join(list(output[0])[1:5])) 获取的,它为我们提供了字符串中从位置1 到位置4 的数字,该位置位于列表output 中的位置0,然后我们join() 将它们包装在int 中,因为要杀死pid,我们需要一个整数。
我的程序给出的输出是:

rahul@RNA-HP:~$ python3 so5.py
7982
7982
7990

这里7982是我们子进程的pid,7990是我们stroke.png的pid
希望对你有帮助
如果有什么可以改进的,请发表评论。

【讨论】:

  • 我认为是-Ao而不是macOS用户的-eo,用于列出过程。
  • 快速旁注(我知道您是从 OP 复制的):使用 SIGKILL 指示进程终止几乎是不合理的。当进程在收到 SIGTERM 后拒绝退出时,SIGKILL 将用作最后的手段。 SIGKILL 是立即终止的命令;接收进程无法执行干净关闭的例程(例如关闭连接、完成待处理的事务、保存未保存的数据)。因此,它可能会导致数据损坏。最好发送 SIGTERM。
  • 是的,我通常使用 -9,它是 SIGTERM 并且也用于此类进程。感谢您指出。
  • 呃,不 :) 9 SIGKILL。如果no signal is explicitly specifiedkill <pid> 发送 SIGTERM (15)。 Here's 信号编号列表。
  • 我一定又搞糊涂了,谢谢。
猜你喜欢
  • 2019-07-11
  • 2019-04-01
  • 2018-12-07
  • 2019-03-25
  • 2019-03-15
  • 2019-07-26
  • 2019-05-05
  • 1970-01-01
  • 2019-09-01
相关资源
最近更新 更多