Shell 脚本发送信号给 C 应用程序,让 C 应用程序回收线程资源后自行退出。
下面分别给出一个 Shell 脚本和 C 程序的例子,实现通过 Shell 脚本发送信号给 C 应用程序,让 C 应用程序回收线程资源后自行退出。
原理
在 Linux 系统中,我们可以使用信号机制来实现进程间的通信。Shell 脚本可以使用 kill
命令向指定的进程发送信号,而 C 程序可以使用 signal
或 sigaction
函数来捕获这些信号,并在信号处理函数中进行线程资源的回收和程序的退出操作。
C 程序示例
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <pthread.h>
#include <unistd.h>// 全局变量,用于标记是否收到终止信号
volatile sig_atomic_t terminate = 0;// 线程函数
void *thread_function(void *arg) {while (!terminate) {printf("线程正在运行...\n");sleep(1);}printf("线程收到终止信号,开始清理资源...\n");// 这里可以添加更多的资源清理代码pthread_exit(NULL);
}// 信号处理函数
void signal_handler(int signum) {if (signum == SIGTERM) {printf("收到 SIGTERM 信号,开始终止程序...\n");terminate = 1;}
}int main() {pthread_t thread;// 注册信号处理函数signal(SIGTERM, signal_handler);// 创建线程if (pthread_create(&thread, NULL, thread_function, NULL) != 0) {perror("线程创建失败");return 1;}// 等待线程结束pthread_join(thread, NULL);printf("所有线程资源已回收,程序退出...\n");return 0;
}
代码解释
- 全局变量
terminate
:用于标记是否收到终止信号,volatile sig_atomic_t
确保在多线程环境下该变量的访问是原子的。 - 线程函数
thread_function
:在一个循环中持续运行,直到terminate
变为 1,表示收到终止信号,然后进行资源清理并退出线程。 - 信号处理函数
signal_handler
:当收到SIGTERM
信号时,将terminate
标记为 1,通知线程停止运行。 - 主函数
main
:注册信号处理函数,创建线程,并等待线程结束。
Shell 脚本示例
#!/bin/bash# 编译 C 程序
gcc -o my_program my_program.c -lpthread# 启动 C 程序
./my_program &
pid=$! # 获取 C 程序的 PID# 等待一段时间
sleep 5# 发送 SIGTERM 信号给 C 程序
kill -SIGTERM $pid# 等待 C 程序退出
wait $pidecho "C 程序已退出"
代码解释
- 编译 C 程序:使用
gcc
编译 C 程序,并生成可执行文件my_program
。 - 启动 C 程序:使用
&
符号将 C 程序放到后台运行,并使用$!
获取其 PID。 - 等待一段时间:使用
sleep
命令等待 5 秒,让 C 程序有足够的时间运行。 - 发送信号:使用
kill -SIGTERM
命令向 C 程序发送SIGTERM
信号。 - 等待程序退出:使用
wait
命令等待 C 程序退出,并打印退出信息。
运行步骤
- 将上述 C 代码保存为
my_program.c
,将 Shell 脚本保存为send_signal.sh
。 - 给 Shell 脚本添加执行权限:
chmod +x send_signal.sh
。 - 运行 Shell 脚本:
./send_signal.sh
。
通过以上步骤,你可以看到 Shell 脚本成功发送信号给 C 程序,C 程序在收到信号后回收线程资源并退出。