如何向fork+execl创建的子进程发送信号?含启停控制场景
让bar控制foo启停及发送其他信号的实现方案
嘿,你的需求很清晰——用bar来启动并控制那个一开始就暂停的foo程序,对吧?目前你的bar代码有个小问题:fork之后没保存子进程的PID,导致没法精准给foo发信号。咱们来修改一下,让bar完全掌控foo的运行状态。
先回顾下你的基础代码,我稍微补全了头文件(不然编译会报错):
foo程序代码
#include <stdio.h> #include <signal.h> #include <unistd.h> int main(int argc, char * argv[]) { kill(getpid(), SIGSTOP); while(1) { printf("foo\n"); // 加个sleep避免输出刷屏,方便观察效果 sleep(1); } return 0; }
修改后的bar程序代码
核心就是保存子进程PID,然后用kill函数发送各种信号:
#include <stdio.h> #include <signal.h> #include <unistd.h> #include <sys/wait.h> int main(int argc, char * argv[]) { pid_t pid = fork(); if (pid == 0) { // 子进程:执行foo,注意路径要对(如果和bar同目录就用./foo) execl("./foo", "foo", NULL); // 如果execl执行失败,打印错误信息 perror("Failed to execute foo"); return 1; } else if (pid > 0) { // 父进程:这里就是控制逻辑的核心 printf("Foo process started with PID: %d\n", pid); // 先等1秒,确保foo已经执行了SIGSTOP进入暂停状态 sleep(1); // 发送SIGCONT,让foo恢复打印 printf("Sending SIGCONT to foo...\n"); kill(pid, SIGCONT); // 让foo运行3秒 sleep(3); // 发送SIGSTOP,暂停foo的打印 printf("Sending SIGSTOP to foo...\n"); kill(pid, SIGSTOP); // 等待2秒,确认foo确实暂停了 sleep(2); // 再次发送SIGCONT恢复运行 printf("Sending SIGCONT again to resume foo...\n"); kill(pid, SIGCONT); // 再运行3秒后,发送SIGTERM终止foo sleep(3); printf("Sending SIGTERM to terminate foo...\n"); kill(pid, SIGTERM); // 等待子进程结束,避免产生僵尸进程 waitpid(pid, NULL, 0); } else { // fork失败的情况,打印错误 perror("Failed to fork process"); return 1; } return 0; }
关键知识点说明
- 保存子进程PID:fork成功后,父进程会获得子进程的PID,这是后续给
foo发信号的唯一标识,必须保存好。 - 常用信号说明:用
kill(pid, signal)函数就能给指定PID的进程发信号,常用信号包括:SIGCONT:恢复暂停的进程SIGSTOP:暂停进程(无法被捕获或忽略)SIGTERM:请求进程终止(可以被捕获处理)SIGKILL:强制终止进程(无法被捕获,慎用)
- 错误处理:添加
perror可以快速定位fork或execl失败的原因,调试起来更方便。 - 避免僵尸进程:用
waitpid等待子进程退出,不然子进程终止后会变成僵尸进程,占用系统资源。
编译运行步骤
- 编译两个程序:
gcc foo.c -o foo gcc bar.c -o bar - 运行
bar:
你会看到清晰的控制流程:foo先暂停,然后开始每秒打印"foo",3秒后暂停,2秒后恢复,最后被终止。./bar
内容的提问来源于stack exchange,提问作者itsmarziparzi
相关产品推荐
相关产品推荐

