首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Linux 平台 C/C++ 開發基礎 (三):行程控制與訊號處理

     編輯:關於C語言

建立子行程:fork()

#include 
pid_t fork(void);
// 子行程返回 0,父行程返回子行程 PID,失敗返回 -1

經典 fork 陷阱:殭屍行程

子行程結束後,若父行程未呼叫 wait/waitpid 回收其退出狀態,子行程進入「殭屍」狀態 (Zombie),佔用 PID 與進程表項目。大量殭屍會耗盡 PID 資源導致無法建立新行程。

兩種回收策略

1. 同步阻塞回收:waitpid()

pid_t waitpid(pid_t pid, int *status, int options);
// pid > 0: 等待特定子行程
// pid = -1: 等待任一子行程
// options: WNOHANG (非阻塞), WUNTRACED (回報停止狀態)

父行程呼叫 waitpid 阻塞直到子行程結束,適合簡單主從模型。

2. 非同步訊號驅動回收:SIGCHLD + 訊號處理器

#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 回收
}

適用於高併發伺服器,父行程不阻塞,透過訊號異步回收。

訊號處理核心 API (signal.h)

函式用途
signal(sig, handler)簡易註冊 (不可靠,語意跨平台差異大,不推薦)
sigaction(sig, &act, &oldact)標準、可靠、完整控制 (掩碼、旗標、替代堆疊)
sigemptyset/set/add/del/procmask訊號集合操作
kill(pid, sig)發送訊號
raise(sig)對自己發送訊號

關鍵旗標 SA_RESTART

系統呼叫被訊號中斷時,預設返回 EINTR。設定 SA_RESTART 讓核心自動重啟被中斷的系統呼叫 (如 read, accept),簡化錯誤處理邏輯。

exec 系列:載入新程式映像

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)、執行緒池、鎖自由資料結構、記憶體模型與原子操作。敬請期待。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved