kill_process released the PTY master while the PTY reader thread was
still blocked in read(). ptyprocess wraps the master in a BufferedRWPair,
so close() waits on the buffer lock the reader holds, and that read only
ends when every holder of the slave side is gone. A descendant that
setsid()s past the kill keeps it open, so the kill never returned (and on
the TTL prune path the same close runs under ProcessRegistry._lock).
Leave the close to the reader while it is alive: its own teardown
(_finish_reader -> _move_to_finished) releases the PTY once its read ends.