关闭这组进程的最佳方法是什么?

发布于 2024-09-19 11:05:13 字数 530 浏览 8 评论 0原文

我有以下一组进程,需要由第一个列出的进程以编程方式关闭,该进程是我正在编码的 C 程序。

PID   PGRP  SESN  PPID USER     TTY  CMD 
6553  6553  6553     1 root     ?        ./startserv
6554  6553  6553  6553 root     ?        expect -- /usr/bin/unbuffer ./srcds_run...
6555  6555  6555  6554 root     pts/1    /bin/sh ./srcds_run -autoupdate -game c...
6565  6555  6555  6555 root     pts/1    ./srcds_linux -autoupdate -game cstrike...

在这种情况下我通常手动执行的是kill 6553 6555。显然我知道我自己的pid,但是编写诸如“kill my pid + 2”之类的代码似乎有点愚蠢(尽管看起来这[几乎]总是有效。 帮助?

I have the following group of processes, which need to be closed programmatically by the first listed process, which is a C program that I am coding.

PID   PGRP  SESN  PPID USER     TTY  CMD 
6553  6553  6553     1 root     ?        ./startserv
6554  6553  6553  6553 root     ?        expect -- /usr/bin/unbuffer ./srcds_run...
6555  6555  6555  6554 root     pts/1    /bin/sh ./srcds_run -autoupdate -game c...
6565  6555  6555  6555 root     pts/1    ./srcds_linux -autoupdate -game cstrike...

What I usually do by hand in this situation is kill 6553 6555. Obviously I know my own pid, but it seems a bit silly to code something like "kill my pid + 2" (although it seems that this would [almost] always work. Help?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

笑饮青盏花 2024-09-26 11:05:13

这些答案都不是非常正确 - 处理此问题的最简单方法是将进程放入进程组中(子进程继承父进程的进程组,因此您的闭源二进制文件也应该很好)通过 getpgrp/setpgrp,然后通过 killpg,保证所有进程同时收到信号,没有任何竞争条件导致子进程分叉在正确的时间逃跑。

None of these answers are very correct - the easiest way to handle this is to put the processes in a process group (child processes inherit the parent's process group, so your closed-source binaries should be good too) via getpgrp/setpgrp, then kill them all in one fell-swoop via killpg, which guarantees that all of them will receive the signal at the same time, without any race conditions which would let a child process forked at the right time to escape.

烟花易冷人易散 2024-09-26 11:05:13

这听起来像是一个全面糟糕的设计。为什么你需要这样的东西?对于您的 startserv 进程来说,将其他进程作为子进程启动是否更有意义,在这种情况下杀死它们很简单?你想达到什么目的?

This sounds like an all-around bad design. Why do you need it like that? Would it make more sense for your startserv process to launch others as child processes, in which case killing them is simple? What are you trying to achieve?

人│生佛魔见 2024-09-26 11:05:13

从kill(2)系统调用的手册页来看:

如果pid为负但不是-1,则将sig发送到其进程组ID等于pid的绝对值且其进程组ID等于pid的绝对值的所有进程(一组未指定的系统进程除外)该进程有权发送信号。

编辑

(我在这里要求澄清,但我需要注释区域中没有的空间和格式)

所以 pstree 将打印:

startserv --- expect --- /bin/sh --- srcds_linux

对组进行分组将是:

{startserv --- expect} --- {/bin/sh --- srcds_linux}

startserv 你想要杀死 expect/bin/shsrcds_linux,但杀死 expect 不会导致 期望杀死它的直接子级(更不用说该子级是其领导的组)。

更多建议

除了 SIGKILL (9) 之外,使用诸如 SIGTERM 之类的某些信号杀死 Expect 可能会导致 expect 杀死其子级(并且也许是组)在终止之前为您服务,但您可能已经尝试过。

只不过,您可以尝试查看 /proc/*/stat 来构建进程树,并找到您的 expect 进程(您已经知道它的 pid),然后杀死它及其所有孩子。这并不完美,因为它不是原子的(/bin/sh 可以分叉更多子进程或其他东西),但如果您也想尝试捕获它,您可以发送此子树中的所有进程 SIGSTOP 意识到它们位于 expect 子树下以稳定该树。然后向他们发送更强的杀戮,可能后跟一个SIGCONT

实现此目的的一种更自动的方法是让 startserv 创建一个 psudoterminal 来运行 expect (及其后代),然后关闭 psudoterminal 的控制端并希望所有这些程序都会因 SIGHUP 而终止。

From the kill(2) system call's man page:

If pid is negative but not -1, sig is sent to all processes (except an unspecified set of system processes) whose process group ID is equal to the absolute value of pid and for which the process has permission to send a signal.

EDIT

(I'm asking for clarification here, but I need room and formatting that aren't available in the comment area)

So pstree would print:

startserv --- expect --- /bin/sh --- srcds_linux

And grouping the groups would be:

{startserv --- expect} --- {/bin/sh --- srcds_linux}

And from startserv you want to kill expect, /bin/sh, and srcds_linux, but killing expect does not result in expect killing its immediate child (much less the group that that child is the head of).

Some more suggestions

It may be that killing expect with some signal besides SIGKILL (9) such as SIGTERM might cause expect to kill its child (and maybe group) for you before terminating itself, but you may have already tried that.

Baring that you could try looking through /proc/*/stat to build a process tree, and find your expect process (you already know its pid), and then kill it and all of its children. This isn't perfect since it's not atomic (/bin/sh could fork some more children or something), but if you want to try to catch that as well you could send all processes in this sub-tree SIGSTOP as realize that they are under the expect sub-tree to stabilize that tree. Then send them all a stronger kill possibly followed by a SIGCONT.

A more automatic way to accomplish this would be to have startserv create a psudoterminal to run expect (and its descendants) on and then close the controlling side of the psudoterminal and hope that all of those programs die on SIGHUP.

汹涌人海 2024-09-26 11:05:13

看起来最简单的方法就是使用 bash。我可以简单地捕获 ps axo pid,ppid 的输出。我已经让第一个进程生成一个带有 pid 的锁定文件,因此 bash 脚本将能够使用父进程 pid 的 ppid 查找第一个项目,并将 SIGTERM 与父进程一起发送。

It seems like the easiest way to do this is simply going to be to use bash. I can simply capture the output of ps axo pid,ppid. I already have the first process generate a lock file with its pid so a bash script would be able to look up the first item with a ppid of the parent's pid and send it a SIGTERM along with the parent.

一个人练习一个人 2024-09-26 11:05:13

最后我的解决方案是:
获取父进程从程序(期望进程)中派生的子进程的 pid。
将该 pid 与第一个进程的 pid 一起写入锁定文件。
编写一个 bash 脚本,查找哪些进程的父进程具有第二个进程的 pid。
杀死第一个进程和 bash 脚本返回的进程 ID。一切都干净地结束。这种方法最好使用killpg命令,我会看一下。

In the end my solution was:
get the pid of the child that the parent forks from within the program (the expect process).
Write that pid to a lock file along with the pid of the first process.
Write a bash script that looks up what processes have a parent that has the pid of the of the second process.
Kill the first process and the process id returned by the bash script. Everything terminates cleanly. It is possible that it would be best to use the killpg command with this method, I will take a look at that.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文