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

Reentrant Function ใน C/C++: ฟังก์ชันที่ปลอดภัยต่อ Interrupt และ Recursion

Reentrant Function คือฟังก์ชันที่สามารถ Interrrupt ได้ระหว่างการทำงาน แล้วกลับมาทำงานต่อได้ถูกต้อง** (Re-enter) เหมาะสำหรับ:

  • Interrupt Service Routines (ISR)
  • Signal Handlers
  • Recursive Algorithms
  • Multi-threaded Environments (พื้นฐาน)

เงื่อนไขของ Reentrant Function

เงื่อนไขเหตุผล
1. ไม่ใช้ Global/Static VariablesISR/Thread อื่นอาจเปลี่ยนค่า -> Inconsistent State
2. ไม่เรียก Non-Reentrant FunctionsLibrary Functions หลายตัว Non-Reentrant (strtok, rand, localtime)
3. ไม่แก้ไข Code ตัวเอง (Self-Modifying Code)Code Integrity
4. ใช้ Stack/Local Variables เท่านั้นแต่ละ Invocation มี Stack Frame แยกกัน
5. ไม่ใช้ Shared Hardware Resources โดยไม่มี LockRegisters, Peripherals

ตัวอย่าง Non-Reentrant


int globalCounter = 0; // Global State

int nonReentrant(int x) {
    globalCounter += x; // ใช้ Global -> Non-Reentrant
    return globalCounter;
}

int alsoNonReentrant(int x) {
    return nonReentrant(x) * 2; // เรียก Non-Reentrant -> Non-Reentrant
}

ตัวอย่าง Reentrant


// Pure Function: Output ขึ้นอยู่กับ Input เท่านั้น, No Side Effects
int reentrant(int x) {
    return x * 10;
}

int reentrant2(int x) {
    return reentrant(x) * 20; // เรียก Reentrant -> Reentrant
}

// Thread-Local Storage (C++11) - Reentrant สำหรับ Thread
thread_local int tlsCounter = 0;

int tlsReentrant() {
    return ++tlsCounter; // แต่ละ Thread มี Counter ของตัวเอง
}

Reentrant vs Thread-Safe

คุณสมบัติReentrantThread-Safe
FocusSingle Thread: Interrupt/RecursionMulti-Thread: Concurrent Access
MechanismNo Shared State, Pure StackSynchronization (Mutex, Atomic)
RelationshipReentrant → Thread-Safe (ถ้าไม่มี Shared State)Thread-Safe ↛ Reentrant (Mutex ไม่ช่วย Interrupt)

Standard Library: Reentrant Versions (POSIX)

หลาย Functions มี `_r` Suffix Version ที่ Reentrant:

  • strtok → strtok_r
  • rand → rand_r
  • localtime → localtime_r
  • getpwnam → getpwnam_r

C++ Modern: Thread Safety แทน Reentrancy


// แทน Global State + Reentrancy
// ใช้ Thread-Local หรือ Atomic หรือ Mutex

// Thread-Local: แต่ละ Thread แยก State
thread_local std::mt19937 gen(std::random_device{}());

// Atomic: Shared State แบบ Safe
std::atomic sharedCounter{0};

// Immutable/Pure Functions: Reentrant โดยธรรมชาติ
int pureAdd(int a, int b) { return a + b; }

สรุป

Reentrant Function = No Shared State (Global/Static) + Only Calls Reentrant Functions สำคัญสำหรับ ISR, Signal Handlers, Recursion ใน Multi-threading ใช้ std::atomic, Mutex, Thread-Local Storage แทนการพยายามทำให้ Reentrant ทุกอย่าง