PID reuse & signals
Thread controls a process through a proc_open handle;
Signal controls one through a bare PID. That difference is why one is safe for
lifecycle management and the other needs care.
Why Thread is reliable
Thread never signals a raw number in a vacuum. isAlive(), join(), and every
signal method check the proc_open handle via proc_get_status, which is bound to the
exact child the parent spawned. When that process exits and is reaped, the handle knows —
there is no window where the handle could point at some other process.
Why raw PIDs are risky
Signal calls posix_kill($pid, ...) on a number you supply. PIDs are a finite, reused
resource: once a process exits and is reaped, the OS is free to hand its number to a
completely unrelated process. So a PID you captured a moment ago can, by the time you signal
it, belong to something else entirely — and your SIGTERM/SIGKILL lands on the wrong
target.
That’s why Signal is documented as “fresh PIDs only,” and why lifecycle control should go
through Thread.
The zombie subtlety
There’s a sharper edge inside isProcessRunning(). A zombie (state Z) is a process
that has already exited but hasn’t yet been reaped by its parent. A zombie still answers
posix_kill($pid, 0) — the probe returns “exists,” even though the process can do no
work and should count as gone.
So isProcessRunning() doesn’t stop at the probe. After confirming the PID responds, it
checks the process state and treats a zombie as not running:
- Linux — reads
/proc/<pid>/statusand matches^State:\s+Z. - macOS / BSD — runs
ps -o state= -p <pid>(with$pidcast toint, so no shell injection) and checks for a leadingZ.
posix_kill(pid, 0) → false → not running
→ true, state Z → not running (zombie)
→ true, alive → runningPractical rule
Use Thread methods to stop and wait for
work you started. Reach for Signal only with a PID obtained immediately before
the call — e.g. reaping a known, still-live child.
Related
- Signals & exit codes — the signal reference
- Graceful shutdown — stopping work safely
- API reference —
Signalmethods