| 函數 | 頭文件 | 用途 | 關鍵差異 |
|---|---|---|---|
exit(status) | stdlib.h | 正常終止,刷新 I/O 緩衝區,調用 atexit 登記函數 | 標準庫函數,確保資料落盤 |
_exit(status) | unistd.h | 直接進入內核終止,不刷新緩衝區,不調用 atexit | 系統調用,適用 fork 後子進程錯誤退出 |
atexit(func) | stdlib.h | 登記無參數清理函數,正常退出時按逆序調用 | 最多 32 個,返回 0 成功 |
on_exit(func, arg) | stdlib.h | 登記帶參數清理函數(已棄用,保留兼容) | 參數含退出狀態與用戶參數 |
abort() | stdlib.h | 發送 SIGABRT 異常終止,產生 core dump | 不調用任何清理函數 |
assert(expr) | assert.h | 宏,expr 為假時輸出訊息並 abort | 定義 NDEBUG 可禁用 |
/* exit_demo.c */
#include <stdio.h>
#include <stdlib.h>
int main() {
printf("Using exit...\n");
printf("This is the content in buffer"); // 無換行,留在緩衝區
exit(0);
}
/* _exit_demo.c */
#include <stdio.h>
#include <unistd.h>
int main() {
printf("Using _exit...\n");
printf("This is the content in buffer");
_exit(0);
}
結果:exit 版本輸出兩行;_exit 版本僅輸出第一行(緩衝區未刷新)。
調用 exit 後,進程不會立即消失,而是留下僵屍進程(Zombie),佔用極少資源,僅保留退出狀態供父進程 wait 收集。父進程未收集會導致僵屍累積。
exit()。fork() 後子進程出錯需立即退出:_exit()(避免雙重刷新標準輸出)。abort()。