Linux 下利用信号机制实现进程通信

1、登录 root 用户:

su - root # 输入密码即可

2、准备环境

确保你的 CentOS 系统已安装 GCC 编译器:

‍sudo yum install gcc -y

如果无法连接到官方镜像站点 (mirrorlist.centos.org),通常是由于 网络连接问题 或 DNS 解析失败 导致的
修改镜像源
(1) 备份原有 repo 文件

sudo mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup

(2) 下载阿里云镜像源

sudo curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo

(3) 清理缓存并更新

sudo yum clean all sudo yum makecache sudo yum update

3、创建并编辑源代码文件

使用 vi 或 nano 创建 C 程序文件:

vi signal_comm.c

按 i 进入编辑模式,粘贴下面的完整代码,然后按 ESC 输入 :wq 保存退出。

#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <signal.h> #include <sys/types.h> pid_t child_pid; // 子进程的信号处理函数 void child_signal_handler(int sig) { if (sig == SIGUSR1) { printf("Bye.World!\n"); exit(0); } } // 子进程函数 void child_process() { // 设置信号处理函数 signal(SIGUSR1, child_signal_handler); while (1) { printf("I am Child Process, alive!\n"); sleep(2); } } int main() { // 创建子进程 child_pid = fork(); if (child_pid < 0) { perror("fork failed"); exit(1); } if (child_pid == 0) { // 子进程代码 child_process(); } else { // 父进程代码 char answer; while (1) { printf("To terminate Child Process. Yes or No?\n"); scanf(" %c", &answer); // 注意空格,跳过空白字符 if (answer == 'Y' || answer == 'y') { // 发送SIGUSR1信号给子进程 kill(child_pid, SIGUSR1); break; } else if (answer == 'N' || answer == 'n') { sleep(2); // 延迟2秒 } else { printf("Please answer Y or N.\n"); } } // 等待子进程结束 wait(NULL); printf("Child process has been terminated.\n"); } return 0; }
程序说明 信号处理: 子进程使用signal(SIGUSR1, child_signal_handler)注册了SIGUSR1信号的处理函数 当收到SIGUSR1信号时,会打印"Bye.World!"并退出 子进程行为: 进入无限循环,每2秒打印一次"I am Child Process, alive!" 收到SIGUSR1信号后执行信号处理函数并退出 父进程行为: 询问用户是否终止子进程 如果回答'N',等待2秒后再次询问 如果回答'Y',向子进程发送SIGUSR1信号 使用wait(NULL)等待子进程结束 关键函数: fork() - 创建子进程 signal() - 注册信号处理函数 kill() - 向指定进程发送信号 wait() - 等待子进程结束 编译和运行 将代码保存为signal_comm.c 编译:gcc signal_comm.c -o signal_comm 运行:./signal_comm 注意事项 SIGUSR1是用户自定义信号,编号为10 使用kill()发送信号需要知道目标进程的PID 信号处理函数应尽量简单,避免使用不可重入函数 父进程使用wait()避免产生僵尸进程

4、编译程序

gcc signal_comm.c -o signal_comm

成功后会生成可执行文件 signal_comm。

5、运行程序

./signal_comm

6、操作示例

程序运行后你会看到

I am Child Process, alive! To terminate Child Process. Yes or No?
输入 N 然后回车:子进程会继续每2秒输出状态 输入 Y 然后回车:会看到子进程输出 Bye.World! 然后退出

7、验证进程通信

可以打开另一个终端窗口,用 ps 命令观察进程状态:

ps aux | grep signal_comm

发送信号测试(不推荐手动操作,程序已自动处理):

kill -SIGUSR1 [子进程PID]

8、可能遇到的问题及解决

问题 1:编译错误‘’signal.h not found’‘

sudo yum install glibc-headers

问题 2:权限不足

chmod +x signal_comm

问题 3:程序无法终止
强制结束:

pkill signal_comm

关键点说明
信号机制:

SIGUSR1 是用户自定义信号(编号 10)

使用 kill() 发送信号需要知道目标 PID

进程管理:

父进程通过 wait() 回收子进程资源

用 ps 命令可以查看运行状态

CentOS 特性:

默认已安装基础开发工具

信号行为符合 POSIX 标准

  • Linux

    Linux 是一套免费使用和自由传播的类 Unix 操作系统,是一个基于 POSIX 和 Unix 的多用户、多任务、支持多线程和多 CPU 的操作系统。它能运行主要的 Unix 工具软件、应用程序和网络协议,并支持 32 位和 64 位硬件。Linux 继承了 Unix 以网络为核心的设计思想,是一个性能稳定的多用户网络操作系统。

    952 引用 • 944 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...