Linux SIGCHLD訊號處理
SIGCHLD的產生條件
1、子程式終止時 2、子程式接收到SIGSTOP訊號停止時 3、子程式處在停止態,接受到SIGCONT後喚醒時
原始碼signal_test.c
void handle_sig_child() { int status; pid_t pid; pid = waitpid(-1, &status, WUNTRACED | WCONTINUED); printf("recv child pid %d \n", pid); if(WIFEXITED(status)) printf("child process exited with %d\n", WEXITSTATUS(status)); else if(WIFSIGNALED(status)) printf("child process signaled with %d\n", WTERMSIG(status)); else if(WIFSTOPPED(status)) printf("child process stoped\n"); else if(WIFCONTINUED(status)) printf("child process continued\n"); } int main(int argc, char** argv) { pid_t pid; /*捕捉SIGCHLD訊號*/ signal(SIGCHLD, handle_sig_child); pid = fork(); if(pid == 0) { sleep(5); printf("child PID [%d]\n", getpid()); exit(0); } else if(pid != -1) { while(1) sleep(1); } else { printf("fork error\n"); } }
執行結果:
where@ubuntu:~$ ./sigal_child_test child PID [9881] child PID [9881] return [0]
單個子程式的時候可以這麼處理,但是如果有多個子程式,如果多個子程式在極短的時間類同時退出產生SIGCHLD資訊,那麼由於未決訊號集不支援排隊,有可能有些訊號就不執行了。看下面的例子:
void handle_sig_child() { int status; pid_t pid; pid = waitpid(-1, &status, WUNTRACED | WCONTINUED); printf("recv child pid %d \n", pid); if(WIFEXITED(status)) printf("child process exited with %d\n", WEXITSTATUS(status)); else if(WIFSIGNALED(status)) printf("child process signaled with %d\n", WTERMSIG(status)); else if(WIFSTOPPED(status)) printf("child process stoped\n"); else if(WIFCONTINUED(status)) printf("child process continued\n"); } int main(int argc, char** argv) { pid_t pid; /*捕捉SIGCHLD訊號*/ signal(SIGCHLD, handle_sig_child); int count = 0; AGAIN: pid = fork(); //fork十次 if(pid == 0) { sleep(5); printf("child PID [%d]\n", getpid()); exit(0); } if(++count < 10) goto AGAIN; while(1) sleep(1); }
執行結果:
$ ./a.out child PID [7785] child PID [7784] child PID [7783] child PID [7782] child PID [7781] child PID [7787] child PID [7788] child PID [7780] child PID [7779] child PID [7786] recv child pid 7779 child process exited with 0 recv child pid 7780 child process exited with 0 recv child pid 7781 child process exited with 0
上面的結果產生十個子程式,退出後產生十個SIGCHLD,但是隻執行了3次訊號處理函式。
$ ps -ef where 7778 3197 0 18:34 pts/2 00:00:00 ./a.out where 7782 7778 0 18:34 pts/2 00:00:00 [a.out] <defunct> where 7783 7778 0 18:34 pts/2 00:00:00 [a.out] <defunct> where 7784 7778 0 18:34 pts/2 00:00:00 [a.out] <defunct> where 7785 7778 0 18:34 pts/2 00:00:00 [a.out] <defunct> where 7786 7778 0 18:34 pts/2 00:00:00 [a.out] <defunct> where 7787 7778 0 18:34 pts/2 00:00:00 [a.out] <defunct> where 7788 7778 0 18:34 pts/2 00:00:00 [a.out] <defunct> where 7790 4193 0 18:34 pts/18 00:00:00 ps -ef
出現未回收的情況,我們需要改進一下回收函式。
void handle_sig_child() { int status; pid_t pid; do { pid = waitpid(-1, &status, WUNTRACED | WCONTINUED | WNOHANG); printf("recv child pid %d \n", pid); if(WIFEXITED(status)) printf("child process exited with %d\n", WEXITSTATUS(status)); else if(WIFSIGNALED(status)) printf("child process signaled with %d\n", WTERMSIG(status)); else if(WIFSTOPPED(status)) printf("child process stoped\n"); else if(WIFCONTINUED(status)) printf("child process continued\n"); }while(pid != -1); } int main(int argc, char** argv) { pid_t pid; /*捕捉SIGCHLD訊號*/ signal(SIGCHLD, handle_sig_child); int count = 0; AGAIN: pid = fork(); if(pid == 0) { sleep(5); printf("child PID [%d]\n", getpid()); exit(0); } if(++count < 10) goto AGAIN; while(1) sleep(1); }
執行結果:
$ ./a.out child PID [7851] child PID [7852] child PID [7847] child PID [7850] child PID [7849] child PID [7853] child PID [7854] child PID [7855] child PID [7856] child PID [7848] recv child pid 7847 child process exited with 0 recv child pid 7848 child process exited with 0 recv child pid 7849 child process exited with 0 recv child pid 7850 child process exited with 0 recv child pid 7851 child process exited with 0 recv child pid 7852 child process exited with 0 recv child pid 7853 child process exited with 0 recv child pid 7854 child process exited with 0 recv child pid 7855 child process exited with 0 recv child pid 7856 child process exited with 0 recv child pid -1 child process exited with 0 recv child pid -1 child process exited with 0
十個子程式都完美回收。
相關文章
- SIGCHLD訊號GC
- linux 訊號與處理Linux
- Linux訊號機制與訊號處理Linux
- Linux訊號處理機制Linux
- linux中的訊號處理與SROPLinux
- Linux 訊號signal處理函式--轉Linux函式
- 訊號處理基本引數
- 【scipy 基礎】--訊號處理
- 訊號、系統與訊號處理邊角雜談
- 處理python中的訊號Python
- php 處理訊號簡單演示PHP
- 訊號處理第二篇——接著談正弦訊號
- Python 音訊訊號處理庫 librosaPython音訊ROS
- MySQL:簡單記錄訊號處理MySql
- MATLAB及其訊號處理基礎Matlab
- Sidekiq 訊號處理原始碼分析IDE原始碼
- 大牛講解訊號與系統以及數字訊號處理
- Linux系統程式設計之訊號中斷處理(下)Linux程式設計
- Linux系統程式設計之訊號中斷處理(上)Linux程式設計
- 細說 ReactiveCocoa 的冷訊號與熱訊號(三):怎麼處理冷訊號與熱訊號React
- linux系統程式設計之訊號(二):訊號處理流程(產生、註冊、登出、執行)Linux程式設計
- xenomai核心解析之訊號signal(二)---xenomai訊號處理機制AI
- 語音訊號處理入門系列(2)——訊號處理中的幾個關鍵概念音訊
- 開心檔之C++ 訊號處理C++
- 科學和工程中的訊號處理
- 通訊訊號處理的一些基本常識
- 我使用過的Linux命令之trap - 在指令碼中處理訊號Linux指令碼
- [訊號處理小結系列4]最頻繁…
- 數字訊號處理c語言程式集C語言
- 科學音訊處理(二):如何使用 Octave 對音訊檔案進行基本數學訊號處理音訊
- 訊號處理技術:現代通訊技術的基石
- Linux ALSA 音訊處理深入解析Linux音訊
- 語音訊號預處理——數字濾波器音訊
- 摘錄nginx 訊號處理方法部分程式碼Nginx
- linux系統程式設計之訊號(七):被訊號中斷的系統呼叫和庫函式處理方式Linux程式設計函式
- MATLAB數字訊號處理(2)LFM脈衝雷達回波處理模擬Matlab
- 音訊訊號處理入門音訊
- 數字訊號處理實驗一(離散時間訊號的MATLAB實現)Matlab