Sigchld Handle

假設你程式有個 select based 的 main loop:
1. (傳統技巧): self pipe: TLPI 63.5.2, p. 1370
2. Linux 新 API, signalfd(): http://www.kernel.org/doc/man-pages/online/pages/man2/signalfd.2.html

multi threaded 程式中,嚴謹講起來若 thread 1 跑了 SIGCHLD handler 更新 pid status table, 同時從 thread 2 中要讀取的話,volatile 還不夠 要用 atomic operations : http://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html#_005f_005fatomic-Builtins (這是最新 gcc 4.7 中對應 C++11/C11 語意的版本,比較舊的 API 是 __sync_synchronize)

C 的 volatile 讓 compiler 不會移動 load / store 但還要讓 CPU 也不會移動才行,所以要插入 memory barrier 指令:
http://en.wikipedia.org/wiki/Memory_barrier
x86 處理器記憶體存取的語意 (memory ordering) 很強,讓你很難觸發這個 bug。

比較建議的 async child process 狀態處理方式是這樣:
1. 啟動外部 process 的地方在跑一個 select based main loop, 啟動外部 process 的時必須註冊一個 callback, 當該 process 結束 / 無法啟動時會被呼叫
2. SIGCHLD handler 很短,只是把 pid 透過一個 pipe 寫出去。該 pipe 會在上面提到的 main loop 中監控 (此即 self pipe trick)
3. main loop 發現 process monitor pipe 變成可讀,select 傳回,讀出 pid,呼叫 waitpid(),觸發註冊的 callback

signal in linux

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License