Reentrant Function คือฟังก์ชันที่สามารถ Interrrupt ได้ระหว่างการทำงาน แล้วกลับมาทำงานต่อได้ถูกต้อง** (Re-enter) เหมาะสำหรับ:
- Interrupt Service Routines (ISR)
- Signal Handlers
- Recursive Algorithms
- Multi-threaded Environments (พื้นฐาน)
เงื่อนไขของ Reentrant Function
| เงื่อนไข | เหตุผล |
|---|---|
| 1. ไม่ใช้ Global/Static Variables | ISR/Thread อื่นอาจเปลี่ยนค่า -> Inconsistent State |
| 2. ไม่เรียก Non-Reentrant Functions | Library Functions หลายตัว Non-Reentrant (strtok, rand, localtime) |
| 3. ไม่แก้ไข Code ตัวเอง (Self-Modifying Code) | Code Integrity |
| 4. ใช้ Stack/Local Variables เท่านั้น | แต่ละ Invocation มี Stack Frame แยกกัน |
| 5. ไม่ใช้ Shared Hardware Resources โดยไม่มี Lock | Registers, 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
| คุณสมบัติ | Reentrant | Thread-Safe |
|---|---|---|
| Focus | Single Thread: Interrupt/Recursion | Multi-Thread: Concurrent Access |
| Mechanism | No Shared State, Pure Stack | Synchronization (Mutex, Atomic) |
| Relationship | Reentrant → Thread-Safe (ถ้าไม่มี Shared State) | Thread-Safe ↛ Reentrant (Mutex ไม่ช่วย Interrupt) |
Standard Library: Reentrant Versions (POSIX)
หลาย Functions มี `_r` Suffix Version ที่ Reentrant:
strtok→strtok_rrand→rand_rlocaltime→localtime_rgetpwnam→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 ทุกอย่าง