Re: OT: fork(): parent or child should run first?

linux-os (Dick Johnson)
2006-01-11T15:21:07Z

On Wed, 11 Jan 2006, Ian Campbell wrote:

> On Wed, 2006-01-11 at 14:55 +0100, Bernd Petrovitsch wrote:
>> On Wed, 2006-01-11 at 13:49 +0000, Ian Campbell wrote:
>>> On Wed, 2006-01-11 at 14:25 +0100, Bernd Petrovitsch wrote:
>>>> Then this leaves the race if an old pid is reused in a newly created
>>>> process before the last instances of that pid is cleaned up.
>>>
>>> The PID won't be available to be re-used until the signal handler has
>>> called waitpid() on it?
>>
>> Yes.
>> But ATM the signal handler calls waitpid() and stores the pid in a
>> to-be-cleaned-pids array (at time X).
>> The main loop at some time in the future (say at time X+N) walks through
>> the to-be-cleaned-pids array and cleans them from the active-childs
>> array.
>
> yuk... I'd say the application is a bit dumb for calling waitpid before
> it is actually prepared for the pid to be reclaimed.
>

The application has no clue (and must not know) the internal workings
of the kernel. In the following code, both forks must work, the case
in which the child executed immediately, and the case in which the
child did some work or slept before it exited.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

int main()
{
pid_t pid;
int status;

switch((pid = fork()))
{
case 0: // child
exit(EXIT_SUCCESS);
case -1: // Error
perror("fork");
exit(EXIT_FAILURE);
default: // Parent
waitpid(pid, &status, 0);
break;
}
switch((pid = fork()))
{
case 0: // child
sleep(10);
exit(EXIT_SUCCESS);
case -1: // Error
perror("fork");
exit(EXIT_FAILURE);
default: // Parent
waitpid(pid, &status, 0);
break;
}
return 0;
}

The code has no clue whether or not the child started before
waitpid was called. It knows it has a valid pid, which is only a
promise that such a child will start execution sometime or
that it once existed and has already expired. That pid must
remain valid until somebody reaps the status of the expired
child.

> A possible solution would be to also defer the waitpid until the main
> loop cleanup function, perhaps flagging the entry in the child array as
> not-active between the signal and that time or moving the pid from the
> active to an inactive array in the signal handler.
>

The pid will (must) always be valid until after the status is reaped.
There should not be any flags used to synchronize anything here. That
pid just cannot be reused until the child is out of the Z state and
its status has been obtained. Then the pid can be reused. It's the
Z state that has historically provided the needed synchronization.

> Ian.
> --
> Ian Campbell
> Current Noise: Sloth - Into The Sun
>
> To err is human,
> To purr feline.
> -- Robert Byrne
>
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>

Cheers,
Dick Johnson
Penguin : Linux version 2.6.13.4 on an i686 machine (5589.71 BogoMips).
Warning : 98.36% of all statistics are fiction.
.

****************************************************************
The information transmitted in this message is confidential and may be privileged. Any review, retransmission, dissemination, or other use of this information by persons or entities other than the intended recipient is prohibited. If you are not the intended recipient, please notify Analogic Corporation immediately - by replying to this message or by sending an email to DeliveryErrors@analogic.com - and destroy all copies of this information, including any attachments, without reading or disclosing them.

Thank you.