You should simply ensure that only the parent process maintains the data-structure of child process status. Really, no child should assume that this data structure is reliable: only the parent really knows, and then only when it formally executes a rendezvous with that child-pid by means of wait()
in the manner that JohnGraham previously described.
Frankly, I would suggest moving the select-loop to a child
process, which subsequently sends the incoming requests to its parent by means of a thread-safe queue. The parent's role thus becomes 100% devoted to keeping up with its unruly children.
But now it only has to deal with waiting for one type
of thing, which is a CPU-initiated not an I/O-initiated event. The child (or children) that are waiting on sockets don't have to wait for anything else. Over a great many years, I have found that this "do-nothing parent" strategy shakes-out a lot of otherwise thorny problems. (Consider, as a prime example, the role of the init
process ("process #1") in any Unix/Linux system . . .)