ทั้ง exit() และ _Exit() ใช้เพื่อจบโปรแกรม แต่มีความแตกต่างในการทำ Cleanup และการเรียก Destructors
exit()
exit() จบโปรแกรมทันที โดยทำ Cleanup ต่างๆ ก่อน:
- เรียกฟังก์ชันที่ลงทะเบียนด้วย
atexit()(LIFO order) - Flush I/O buffers (stdout, stderr, stdin)
- ปิด Stream/ไฟล์ที่เปิดอยู่ทั้งหมด
- เรียก Destructors ของ Object ที่มี Static/Thread Storage Duration (C++)
- คืนค่า Status ให้ Parent Process/OS
ไวยากรณ์
#include <stdlib.h>
void exit(int status_value);
ตัวอย่าง
#include <stdio.h>
#include <stdlib.h>
int main() {
int x = 10;
printf("The value of x : %d\n", x);
exit(0); // จบโปรแกรม ทำ cleanup
printf("Calling of exit()"); // ไม่ถูกพิมพ์
return 0;
}
ผลลัพธ์
The value of x : 10
_Exit() (และ _exit() ใน POSIX)
_Exit() จบโปรแกรม ทันทีโดยไม่ทำ Cleanup ใดๆ:
- ไม่ เรียก
atexit()handlers - ไม่ Flush I/O buffers
- ไม่ เรียก Destructors ของ C++ Objects
- ไม่ ปิดไฟล์/Stream (OS จะปิดให้เมื่อ Process จบ)
- คืนค่า Status ให้ Parent Process/OS
ไวยากรณ์
#include <stdlib.h>
void _Exit(int status_value); // C11/C++11
ตัวอย่าง
#include <stdio.h>
#include <stdlib.h>
int main() {
int x = 10;
printf("The value of x : %d\n", x);
_Exit(0); // จบทันที ไม่ cleanup
printf("Calling of _Exit()"); // ไม่ถูกพิมพ์
return 0;
}
ผลลัพธ์
The value of x : 10
ตารางเปรียบเทียบ
| พฤติกรรม | exit() | _Exit() |
|---|---|---|
| atexit() handlers | ✓ เรียก | ✗ ไม่เรียก |
| Flush I/O buffers | ✓ ใช่ | ✗ ไม่ |
| Close streams/files | ✓ ใช่ | ✗ ไม่ (OS ทำ) |
| C++ Static Destructors | ✓ เรียก | ✗ ไม่เรียก |
| C++ Thread-local Destructors | ✓ เรียก | ✗ ไม่เรียก |
| Signal safety | Unsafe (Async-signal-unsafe) | Safe (Async-signal-safe) |
| มาตรฐาน | C89/C++98 | C11/C++11 |
เมื่อไหร่ควรใช้ _Exit()
- ใน Signal Handler (Async-signal-safe) -
exit()ไม่ปลอดภัยใน Signal Handler - Child Process หลัง
fork()ก่อนexec()- ป้องกัน Double Flush/Double Cleanup - กรณีฉุกเฉินที่ต้องจบทันทีและไม่ต้องการ Cleanup
ฟังก์ชันที่เกี่ยวข้อง
abort()- จบแบบ Abnormal (Core dump, ไม่ Cleanup)atexit()- ลงทะเบียน Cleanup Functionsquick_exit()(C11) - คล้าย exit() แต่ไม่เรียก Destructors, เรียกat_quick_exit()handlers
สรุป
ใช้ exit() สำหรับการจบโปรแกรมปกติ (Normal Termination) เพื่อให้ Cleanup ครบถ้วน ใช้ _Exit() เฉพาะใน Signal Handlers หรือหลัง fork() ก่อน exec() เท่านั้น