fork() 建立的子進程與父進程並發執行,對共享資源 (如全域變數、檔案、終端機) 的存取順序不可預測。需透過同步機制確保有序存取。
int count = 0;
pid = fork();
if (pid > 0) { // 父進程
count++;
printf("Father: count=%d\n", count);
} else if (pid == 0) { // 子進程
count++;
printf("Son: count=%d\n", count);
}
/* 輸出順序不定,count 互不影響 (各自複製體) */
pid = fork();
if (pid > 0) { // 父進程
printf("Father running (PID=%d)\n", getpid());
pid_t child_pid = wait(&status); // 阻塞直到子進程結束
if (child_pid > 0) {
printf("Child %d finished\n", child_pid);
count++; // 現在安全存取
printf("Father: count=%d\n", count);
}
} else if (pid == 0) { // 子進程
printf("Son running (PID=%d)\n", getpid());
count++;
printf("Son: count=%d\n", count);
}
/* 輸出順序固定:子進程先跑完,父進程才繼續 */
| 場景 | 輸出順序 | 說明 |
|---|---|---|
| 無 wait | 交錯不定 | 父子並發,各自獨立 count 副本 |
| 有 wait | 子進程完整輸出 → 父進程輸出 | 父進程阻塞於 wait(),子進程結束後才繼續 |
wait(&status)回傳結束的子進程 PID,status可透過WIFEXITED、WEXITSTATUS宏檢查退出狀態。實務上常搭配訊號處理、waitpid()實現更精細控制。