我的程序总体设计是:
代码大致是这样的:
volatile sig_atomic_t ev_flag = 0;
static void signal_handler(int signum) {
ev_flag = 1;
char msg[] = "Signal caught\n";
write(STDOUT_FILENO, 0, strlen(msg));
}
void install_signal_handler() {
struct sigaction act;
act.sa_handler = signal_handler;
act.sa_flags = SA_RESETHAND;
if (sigaction(SIGINT, &act, 0) + sigaction(SIGABRT, &act, 0) +
sigaction(SIGQUIT, &act, 0) + sigaction(SIGTERM, &act, 0) +
sigaction(SIGPIPE, &act, 0) + sigaction(SIGCHLD, &act, 0) +
sigaction(SIGSEGV, &act, 0) + sigaction(SIGTRAP, &act, 0) < 0) {
perror("sigaction()");
abort();
}
}
int main(void) {
FILE *child_proc;
child_proc = popen(child_proc_cmd, "w");
while (ev_flag == 0) {
if (fwrite(data, 1, data_size, child_proc) != data_size) {
perror("fwrite()");
break;
}
}
printf("\nThe evloop quitted, gracefully\n");
pclose(child_proc);
return 0;
}
这种设计适用于大多数情况,除了一个:如果子进程以某种方式被
kill <pid>
或 kill -KILL <pid>
杀死,我的父进程将无法到达
printf("\nThe evloop quitted, gracefully\n");
如预期的那样,即使调用了我的
signal_handler()
。有什么想法吗?还是我当前设计中的任何错误?
你永远不会调用
install_signal_handler()
,所以你的信号处理程序永远不会被执行。
在信号处理程序中,您将从空指针编写:
write(STDOUT_FILENO, 0, strlen(msg));
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>
volatile sig_atomic_t ev_flag = 0;
static void signal_handler(int signum) {
ev_flag = 1;
char msg[] = "Signal caught :";
char *sig = strsignal(signum);
write(STDOUT_FILENO, msg, strlen(msg)); // Write from buffer
write(STDOUT_FILENO, sig, strlen(sig)); // Write signal string
write(STDOUT_FILENO, "\n", 1);
}
void install_signal_handler()
{
struct sigaction act;
act.sa_handler = signal_handler;
act.sa_flags = SA_RESETHAND;
if (sigaction(SIGINT, &act, 0) + sigaction(SIGABRT, &act, 0) +
sigaction(SIGQUIT, &act, 0) + sigaction(SIGTERM, &act, 0) +
sigaction(SIGPIPE, &act, 0) + sigaction(SIGCHLD, &act, 0) +
sigaction(SIGSEGV, &act, 0) + sigaction(SIGTRAP, &act, 0) < 0) {
perror("sigaction()");
abort();
}
}
int main(void)
{
const char data[] = "Lorem ipsum dolor sit amet\n";
size_t data_size = strlen(data);
const char child_proc_cmd[] = "wc -l";
install_signal_handler(); // Install signal handlers
FILE *child_proc;
child_proc = popen(child_proc_cmd, "w");
while (ev_flag == 0) {
if (fwrite(data, 1, data_size, child_proc) != data_size) {
perror("fwrite()");
break;
}
}
printf("\nThe evloop quitted, gracefully\n");
pclose(child_proc);
return 0;
}
输出:
Signal caught :Child exited
Signal caught :Broken pipe
fwrite(): Broken pipe
The evloop quitted, gracefully