我正在尝试编写一个pkill
类似实用程序,通过搜索某个字符串来匹配进程/proc/pid/environ
并终止它们。但匹配的进程可能会在我终止它之前退出,另一个进程可能会获取它的 pid。在这种情况下,我最终会终止新进程。有没有办法避免这种竞争情况?
我正在尝试编写一个pkill
类似实用程序,通过搜索某个字符串来匹配进程/proc/pid/environ
并终止它们。但匹配的进程可能会在我终止它之前退出,另一个进程可能会获取它的 pid。在这种情况下,我最终会终止新进程。有没有办法避免这种竞争情况?
重新考虑你正在做的事情。不要通过暴力搜索和终止进程,而是寻找一种方法来阻止启动它们的程序启动它们。(例如,如果它是一项不需要的服务,请禁用该服务。)
找出最大 PID 值并计算 PID 重用的概率。Linux 上的进程 ID 是递增分配的,直到它们翻转为止,
kernel.pid_max
在旧发行版中为 2^16,在新发行版中为 2^22,并且您的工具大约同时执行这两个操作(相隔几个指令)——因此,为了实现这一点,系统需要启动 2^22 个新进程,而从不安排您的工具进程在此期间继续运行——如果进程以正常优先级运行,这种情况不太可能发生。升级到最新的内核并使用与进程文件描述符(如和)一起工作的pidfd函数。
pidfd_open()
pidfd_send_signal()
如果您运行的是足够新的 Linux 版本,则可以使用
pidfd_open()
(需要 Linux 5.3 或更新版本)或打开 PID 的目录/proc
(作为使用常规函数的文件,此方法需要 Linux 5.1 或更新版本)来获取与在进行系统调用时open()
由给定 PID 引用的特定进程绑定的文件描述符。然后,您可以使用向该进程发送信号。通过首先打开 PID 文件描述符,然后使用它与进程目录进行交互(而不是单独检查文件),您可以关闭您担心的竞争条件。pidfd_send_signal()
/proc
但一般来说,这只对像这样的工具才有价值
pkill
。如果你只是想杀死你正在管理的进程,你应该使用像 systemd 或 runit 这样的适当的进程管理器,或者如果你不能这样做,至少使用 cgroups,这两者都不存在这个问题。