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
十個子程式都完美回收。
相關文章
- linux 訊號與處理Linux
- linux中的訊號處理與SROPLinux
- 【scipy 基礎】--訊號處理
- 訊號處理基本引數
- 處理python中的訊號Python
- Python 音訊訊號處理庫 librosaPython音訊ROS
- Linux系統程式設計之訊號中斷處理(下)Linux程式設計
- Linux系統程式設計之訊號中斷處理(上)Linux程式設計
- MATLAB及其訊號處理基礎Matlab
- 訊號處理第二篇——接著談正弦訊號
- MySQL:簡單記錄訊號處理MySql
- xenomai核心解析之訊號signal(二)---xenomai訊號處理機制AI
- 開心檔之C++ 訊號處理C++
- 語音訊號處理入門系列(2)——訊號處理中的幾個關鍵概念音訊
- 通訊訊號處理的一些基本常識
- MATLAB數字訊號處理(2)LFM脈衝雷達回波處理模擬Matlab
- 訊號處理技術:現代通訊技術的基石
- Windows10 VS2017 C++訊號處理WindowsC++
- Python語音訊號處理的一些kitPython音訊
- 語音訊號預處理——數字濾波器音訊
- linux故障處理Linux
- 訊號處理板卡學習資料第524篇:基於XCZU15EG的FMC+ 高效能通用訊號處理板卡
- 數字訊號處理:運用FFT簡單濾波FFT
- FPGA數字訊號處理(22)FSK調製技術FPGA
- MATLAB訊號處理——數字濾波器的設計Matlab
- Mac出現這5個警告訊號以及處理方法Mac
- 使用 scipy.fft 進行Fourier Transform:Python 訊號處理FFTORMPython
- 腦機介面例項二:腦電訊號CSP處理腦機介面
- 音訊訊號處理入門音訊
- 【Linux入門教程】4 使用者管理、系統效能分析、系統日誌及日誌分析、訊號機制與訊號處理Linux
- 音訊處理音訊
- Linux文字處理命令Linux
- 語音訊號處理獲取 NFFT 的自定義函式音訊FFT函式
- 數字訊號處理基礎----插值、抽取濾波器
- Room & Kotlin 符號的處理OOMKotlin符號
- linux 訊號機制Linux
- MATLAB音訊訊號處理(一):函式簡易用法(audioread,sound函式)Matlab音訊函式
- win10 wifi訊號弱怎麼回事_win10系統wifi訊號很弱如何處理Win10WiFi
- VPX訊號處理卡設計資料第9篇:基於C6678+XC7V690T的6U VPX訊號處理卡