Start here
Reentrancy vs thread-safety vs async-signal-safety
Reentrant functions avoid static buffers and hidden globals; they work when called recursively or from multiple threads if each call uses only stack parameters. Signal handlers run in a constrained context, calling malloc is unsafe if it might contend with an interrupted malloc.
By the end of this page you should be able to
- Give an example of a C library function that is not reentrant and why.
- Explain why async-signal-safe is smaller than thread-safe.
- Describe how TLS can help separate per-thread state.
Operating systems · Threads
Reentrancy
Safe to interrupt and re-enter
TL;DR
A function is reentrant if it can be called again while an earlier invocation is still in progress **without** relying on a single mutable global in an unsafe way. Reentrancy differs from thread-safety: `strtok` is neither; reentrant versions use explicit state parameters (`strtok_r`).
Summary
Reentrancy matters wherever execution can nest: signals, interrupts, recursive calls, and certain callback chains. Interviewers probe whether you know `strtok_r` vs `strtok` and async-signal-safe lists.
Deeper narrative
Reentrant functions can be interrupted and called again safely without per-invocation static state. Thread-safe is broader; async-signal-safe is narrower still, signal handlers may only call a tiny POSIX subset.
Mechanism (step by step)
Identify saved state
Static locals, hidden globals, errno clobbering in libraries.
Prefer pure stack data
Pass context pointers instead of hidden singletons.
Locking strategy
Recursive mutexes if same thread may re-enter, otherwise refactor.
Signal context
Defer heavy work to thread pool; handler sets atomic flag only.
Key insights
Pure functions win
Hidden globals
Recursive mutexes
Kernel reentrancy
Did you know?
Common pitfalls
Calling malloc in signal handler
Not async-signal-safe, can deadlock if interrupted mid-allocator lock.
Assuming thread-safe == reentrant
Thread-safe may allocate per-thread state; reentrant forbids hidden contention.
Glossary
Async-signal-safe
Idempotent
Recursive mutex
Interview follow-ups
- List three POSIX functions that are async-signal-safe.
- Why is `strtok` not reentrant?
- How does TLS help reentrancy?
Callouts
Signals
Never malloc inside a signal handler unless you know you are async-signal-safe, deadlocks await.
Walkthrough & deep dive
Left: practical “how would I use this?” threads. Right: slower, code-leaning explanations, open one panel at a time so the page does not feel like a wall of sameness.
Walkthrough
Classify
Deep dive
Async-signal-safe
POSIX lists tiny subset: `write`, `_exit`, `kill`, many syscalls disallowed because they take locks internally.
Prefer *_r APIs
char *save = NULL;
strtok_r(buf, " ", &save);Self-check
1Reentrant code avoids…
2`strtok` is problematic because…
3Async-signal-safe means…