进程 A 在运行时打开并映射了数千个文件。那么killl -9 <pid of process A>
发行。然后我对以下两个事件的顺序有疑问。
一)/proc/<pid of process A>
无法访问。
b) 关闭进程A打开的所有文件。
关于这个问题的更多背景:
进程A是一个多线程后台服务。它由 cmd ./process_A args1 arg2 arg3
启动.
还有一个看门狗进程定期(每 1 秒)检查进程 A 是否仍然存在。如果进程 A 已死,则重新启动它。 watchdog检查进程A的方式如下。
1) 收集 /proc/
下的所有数字子目录
2)比较/proc/<all-pids>/cmdline
使用进程 A 的命令行。如果这些是 /proc/<some-pid>/cmdline
匹配,那么进程 A 还活着,什么都不做,否则重启进程 A。
进程A在初始化的时候会做下面的事情。
1) 打开文件A
2) 群文件A
3) mmap fileA 到内存
4) 关闭文件A
进程 A 将在初始化后映射数千个文件。
几分钟后,kill -9 <pid of process A>
发行。
看门狗检测到进程A死亡,重启它。但有时进程 A 停留在 step 2 flock fileA
。 .经过一番调试,我们发现fileA的unlock是在进程A被kill的时候执行的。但有时这个事件会发生在step 2 flock fileA
之后。新工艺。
所以我们猜测通过监视器检查进程存活的方式/proc/<pid of process A>
不正确。
最佳答案
then
kill -9
is issued
这是个坏习惯。你最好发一个SIGTERM
第一的。因为行为良好的流程和设计良好的程序可以捕获它(并在获得 SIGTERM
时很好地和正确地退出...)。在某些情况下,我什至建议:发送 SIGTERM
.等待两三秒钟。发送SIGQUIT
.等两秒钟。最后发一个SIGKILL
信号(针对那些没有正确编写或行为不端的不良程序)。几秒钟后,您可以发送 SIGKILL
.阅读signal(7)和 signal-safety(7) .在多线程但特定于 Linux 的程序中,您可以使用 signalfd(2)或 pipe(7)自欺欺人(Qt 文档中的 explained,但不是特定于 Qt 的)。
如果你的Linux系统是systemd基于此,您可以想象您的 program-A 是使用 systemd 设施启动的。然后您将使用 systemd 工具与它“通信”。在某些方面(我不知道细节),systemd 正在制作 signals几乎过时了。请注意,信号不是多线程友好的,并且在上个世纪是为单线程进程设计的。
we guess the way to check process alive by monitor /proc/ is not correct.
检测进程是否存在(您有足够的权限,例如以您的 uid/gid 运行)的通常(并且更快,并且足够“原子”)的方法是使用 kill(2)信号编号(kill
的第二个参数)为 0。引用该联机帮助页:
If sig is 0, then no signal is sent, but existence and permission
checks are still performed; this can be used to check for the
existence of a process ID or process group ID that the caller is
permitted to signal.
当然,其他进程仍然可以在与它进行任何进一步交互之前终止。因为Linux有抢占式调度。
看门狗进程最好使用kill(
pid-of-process-A , 0)
检查该 process-A 的存在和活跃度。使用 /proc/
pid-of-process-A /
这不是正确的方法。
无论您编写什么代码,process-A 都可能异步消失(特别是,如果它有一些导致段错误的错误)。当一个进程终止时(即使存在段错误),内核 正在处理其文件锁(并“释放”它们)。
关于linux -/proc/<pid> 什么时候被删除?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54822678/