下面分別給出一個 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 程序在收到信號后回收線程資源并退出。