【发布时间】:2021-04-27 09:09:40
【问题描述】:
我目前正在为大学做一个 C 项目。除其他事项外,我应该使用SIGUSR1 向父进程发出信号。
我目前面临的问题是,我还需要等待子进程终止,以便最终安全地关闭所有内容(删除共享内存等)。
目前我正在使用sigaction() 响应信号并使用waitpid() 等待孩子终止(无论如何这是计划^^)。但是当我使用kill() 向父级发送信号时,waitpid() 会停止等待并运行父级的其余部分,即使子级仍在运行。
我觉得我遗漏了一些明显的东西,但我想不通。
非常感谢任何帮助, 保持安全
提姆
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <unistd.h>
void handle_sigusr1(int sig) {
printf("Recieved signal %i.\n", sig);
}
int main() {
pid_t pid;
pid = fork();
if (pid == -1) {
perror("fork:");
return EXIT_FAILURE;
}
else if (pid == 0) {
printf("Hello from the child.\n");
kill(getppid(), SIGUSR1);
sleep(3);
printf("Hello again from the child.\n");
return EXIT_SUCCESS;
}
else {
printf("Hello from the parent.\n");
struct sigaction sa;
sa.sa_handler = &handle_sigusr1;
sigaction(SIGUSR1, &sa, NULL);
int status;
waitpid(pid, &status, 0);
if (WIFEXITED(status))
printf("Exit status: %i\n", WEXITSTATUS(status));
printf("Finished waiting for child.\n");
return EXIT_SUCCESS;
}
}
输出:
Hello from the parent.
Hello from the child.
Recieved signal 10.
Exit status: 0
Finished waiting for child.
tim@schlepptop:signalTest$ Hello again from the child.
PS:WEXITSTATUS(status) 通常是 0,但有时也类似于 16 或 128。
【问题讨论】:
-
如果您阅读 waitpid 的手册页,它会说“它们会阻塞,直到孩子改变状态或信号处理程序中断调用”
-
现在说得通了。有没有其他方法可以只等待进程终止而不是信号?
-
添加到上一条评论 - 检查
waitpid的返回值,并通过再次调用waitpid或退出来做出相应的反应。或者,在安装 sighandler 时设置SA_RESTART。 -
好的,我试试看,如果我找到了解决方案,非常感谢!
-
@kaylum
SA_RESTART不保证所有呼叫都会重新启动。例如,list on the Linuxsigaction()man page 并不是包罗万象的,尽管在这种情况下它确实列出了waitpid()。还有一个永远不会重新启动的功能列表。例如,waitpid()是 not documented as being restarted on Solaris 11。SA_RESTART很有用,但不是万能的。
标签: c linux multithreading signals