Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> การเขียนโปรแกรม C

ความแตกต่างระหว่าง exit() และ _Exit() ใน C/C++

ทั้ง 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 safetyUnsafe (Async-signal-unsafe)Safe (Async-signal-safe)
มาตรฐานC89/C++98C11/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 Functions
  • quick_exit() (C11) - คล้าย exit() แต่ไม่เรียก Destructors, เรียก at_quick_exit() handlers

สรุป

ใช้ exit() สำหรับการจบโปรแกรมปกติ (Normal Termination) เพื่อให้ Cleanup ครบถ้วน ใช้ _Exit() เฉพาะใน Signal Handlers หรือหลัง fork() ก่อน exec() เท่านั้น