#include
pid_t fork(void);
// 子行程返回 0,父行程返回子行程 PID,失敗返回 -1
子行程結束後,若父行程未呼叫 wait/waitpid 回收其退出狀態,子行程進入「殭屍」狀態 (Zombie),佔用 PID 與進程表項目。大量殭屍會耗盡 PID 資源導致無法建立新行程。
pid_t waitpid(pid_t pid, int *status, int options);
// pid > 0: 等待特定子行程
// pid = -1: 等待任一子行程
// options: WNOHANG (非阻塞), WUNTRACED (回報停止狀態)
父行程呼叫 waitpid 阻塞直到子行程結束,適合簡單主從模型。
#include
void sigchld_handler(int sig) {
int status;
while (waitpid(-1, &status, WNOHANG) > 0) {
// 子行程結束,可在此處理 status
}
}
int main() {
struct sigaction sa = {0};
sa.sa_handler = sigchld_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART | SA_NOCLDSTOP; // 不因子行程停止產生訊號
sigaction(SIGCHLD, &sa, NULL);
// fork 子行程...
// 主迴圈繼續工作,子行程結束時自動觸發 handler 回收
}
適用於高併發伺服器,父行程不阻塞,透過訊號異步回收。
| 函式 | 用途 |
|---|---|
signal(sig, handler) | 簡易註冊 (不可靠,語意跨平台差異大,不推薦) |
sigaction(sig, &act, &oldact) | 標準、可靠、完整控制 (掩碼、旗標、替代堆疊) |
sigemptyset/set/add/del/procmask | 訊號集合操作 |
kill(pid, sig) | 發送訊號 |
raise(sig) | 對自己發送訊號 |
系統呼叫被訊號中斷時,預設返回 EINTR。設定 SA_RESTART 讓核心自動重啟被中斷的系統呼叫 (如 read, accept),簡化錯誤處理邏輯。
int execl(const char *path, const char *arg, ..., (char *)NULL);
int execv(const char *path, char *const argv[]);
// 成功不返回,失敗返回 -1。常搭配 fork 使用:fork → 子行程 exec
執行緒建立與同步 (pthread_create, mutex, condition variable)、執行緒池、鎖自由資料結構、記憶體模型與原子操作。敬請期待。