我有一个 Linux 进程(我们称之为主进程),它的标准输出通过 shell 的管道运算符 (|) 传送到另一个进程(称为下游进程)。主进程设置为在下游进程崩溃时接收 SIGPIPE 信号。不幸的是,在主进程写入标准输出之前,不会引发 SIGPIPE。有没有办法更快地告诉下游进程已经终止?
一种方法是连续写入下游进程,但这似乎很浪费。另一种方法是有一个单独的看门狗进程来监控所有相关进程,但这很复杂。或者也许有一些方法可以使用 select() 来触发信号。我希望主进程可以自己完成这一切。
当接收器崩溃时,stdout 文件描述符似乎变为“准备读取”:
$ gcc -Wall select-downstream-crash.c -o select-downstream-crash
$ gcc -Wall crash-in-five-seconds.c -o crash-in-five-seconds
$ ./select-downstream-crash | ./crash-in-five-seconds
... five seconds pass ...
stdout is ready for reading
Segmentation fault
选择-下游-crash.c
#include <err.h>
#include <stdio.h>
#include <sys/select.h>
#include <unistd.h>
int main(void)
{
fd_set readfds;
int rc;
FD_ZERO(&readfds);
FD_SET(STDOUT_FILENO, &readfds);
rc = select(STDOUT_FILENO + 1, &readfds, NULL, NULL, NULL);
if (rc < 0)
err(1, "select");
if (FD_ISSET(STDOUT_FILENO, &readfds))
fprintf(stderr, "stdout is ready for reading\n");
return 0;
}
五秒内崩溃.c
#include <stdio.h>
#include <unistd.h>
int main(void)
{
sleep(5);
putchar(*(char*)NULL);
return 0;
}
我在 Linux 上试过这个,但不知道它是否会在其他地方工作。很高兴找到一些解释这一观察的文档。
如果主进程fork
是其他进程,那么它会SIGCHLD
在它们退出时收到通知。