I fork() a parent process to a child, the PID returned by fork() is stored in the parent's memory, then time passes and the child terminates; Now can I determine if the PID value stored in the parent's memory still refers to the same forked child, and how can I ensure that this PID doesn't refer to a different process with the same PID, which may eventually have born after the child terminated?
The operating system cannot reuse the child's PID until the parent has acknowledged that it knows the child has stopped executing.
The parent makes the acknowledgment using the wait and waitpid calls. The children that terminate are kept in a "zombie" state while the parent doesn't call these functions. After these calls return the parent will know that if there's a process running with the same PID that the child had, it's not the child.
For extra safety you might be interested in checking the parent PID of the child process.
You can:
call man 2 wait in parent, to get notification when child dies;
invent your polling protocol between parent and child. If child still the same, it must respond to parent's poll with the same value as it did right after the spawn. You can use some POSIX IPC mechanism for this. This can be useful when your parent has only one execution thread and you can't use threads in parent.
Related
I am learning the wait() method in C. And I know that it blocks the parent process until one of its child processes terminates. But what if the kernel decides to schedule the child first and the child process terminates before parent can call the wait()? Is that the parent will wait there forever(without other interrupts) since it can not observe the return of a child?
In the photo, if the execution sequence is: fork --> HC --> exit -->HP-->wait, then the situation I describe will happen.
No, the parent will not wait forever.
The documentation on wait states:
All of these system calls are used to wait for state changes in a
child of the calling process, and obtain information about the child
whose state has changed. A state change is considered to be: the
child terminated; the child was stopped by a signal; or the child was
resumed by a signal. In the case of a terminated child, performing a
wait allows the system to release the resources associated with the
child; if a wait is not performed, then the terminated child remains
in a "zombie" state .
If a child has already changed state, then these calls return immediately.
But what if the kernel decides to schedule the child first and the
child process terminates before parent can call the wait()?
It is a pretty possible case. If one of the wait family functions is used by the parent or signal(SIGCHLD, SIG_IGN); is called explicitly before forking, it does not turn the child into a zombie even if the parent process is preempted(=not permitted to use CPU at that time).
Moreover, the need of wait or signal-ignorance mentioned is to clean process's unused datas. While using one of the methods, the kernel is told that the child(ren) process is not used anymore. So, you can cleanup unused system resources.
In C programming for Linux, I know the wait() function is used to wait for the child process to terminate, but are there some ways (or functions) for child processes to wait for parent process to terminate?
Linux has an extension (as in, non-POSIX functions) for this. Look up prctl ("process-related control").
With prctl, you can arrange for the child to get a signal when the parent dies. Look for the PR_SET_PDEATHSIG operation code used with prctl.
For instance, if you set it to the SIGKILL signal, it effectively gives us a way to have the children die when a parent dies. But of course, the signal can be something that the child can catch.
prctl can do all kinds of other things. It's like an ioctl whose target is the process itself: a "process ioctl".
Short answer: no.
A parent process can control the terminal or process group of its children, which is why we have the wait() and waitpid() functions. A child doesn't have that kind of control over its parent, so there's nothing built in for that.
If you really need a child to know when its parent exits, you can have the parent send a signal to the child in an atexit() handler, and have the child catch that signal.
In Linux, you can use prctl with the value PR_SET_PDEATHSIG to establish a signal that will be sent to your process when the thread that created it dies. Maybe you find it useful.
When a parent process ends, child process is adopted by init, so it is enough to check in child proces if ppid()==1 or ppid()!= than oryginal PPID
That means the parent process was finished.
If I spawn a process in my linux C program and there are 2 processes in total, a parent process and a child process. I want: if one of these 2 processes exits, the other process also exits.
How to achieve this?
are there any similar source codes?
Note: I don't want to block both processes, e.g, I don't want the parent process to be blocked by wait()
thanks!
In father process you can use the waitpid system call. It will block until the child exits.
In the child process you cannot use waitpid. One option would be that the father will inform the child by sending it a SIGTERM on exit. But this will only work if the father won't get killed using SIGKILL. I would suggest to periodically send a signal using kill with param 0 to the father process. If this fails, the process has terminated.
From the kill(2) man page:
if sig is 0, then no signal is sent, but error checking is still performed; this can be used to check for the existence of a process ID or process group ID.
If the child exits, the parent will be sent a SIGCHLD. If the parent is going to die, it should notify the child somehow, or at least send it a SIGTERM.
http://linux.die.net/man/2/waitpid
Wait for any child process, then exit when you return from waitpid.
If the parent process exits, then the child process becomes a zombie process.
If the child exits, the parent can be notified by the wait system call. You can exit the parent by reading the status of it.
I was reading about the wait() function in a Unix systems book. The book contains a program which has wait(NULL) in it. I don't understand what that means. In other program there was
while(wait(NULL)>0)
...which also made me scratch my head.
Can anybody explain what the function above is doing?
man wait(2)
All of these system calls are used to wait for state changes in
a child of the calling process, and obtain information about the child
whose state has changed. A state change is considered to be: the child terminated; the child was stopped by a signal; or the child was resumed by a signal
So wait() allows a process to wait until one of its child processes change its state, exists for example. If waitpid() is called with a process id it waits for that specific child process to change its state, if a pid is not specified, then it's equivalent to calling wait() and it waits for any child process to change its state.
The wait() function returns child pid on success, so when it's is called in a loop like this:
while(wait(NULL)>0)
It means wait until all child processes exit (or change state) and no more child processes are unwaited-for (or until an error occurs)
a quick google suggests, wait(NULL) waits for any of the child processes to complete
wait(NULL) which should be equivalent to waitpid(-1, NULL, 0)
wait(NULL) waits for all the child processes to complete
In Unix, when a child process in background terminates, it sends a SIGCHLD signal to the parent to inform it that it terminated.
Does the same happen even if the process was in foreground? If so, this means the parent will just ignore it.
Is this right? Or if it is in foreground, then no signal is sent at all?
background and foreground are job control concepts, and are part of the the shell. They are applied to processes and do not affect which process spawned (exec-ed) another process.
A child process is the result of a fork()-exec() call. The child gets a parent pid of the process that executed the fork() call. This is the context of the SIGCHLD signal, the parent pid receives the SIGCHLD signal. It does not matter whether the child process is "foreground" or "background", only the ppid matters on exit of the process.
There's no such thing as foreground child. The term background process is used to simply refer that we are mainly dealing with the parent process (which may create a child processes to do a part its job). When a child process exits SIGCHLD is always sent to parent process. However, the parent process usually ignores it. If parent wants to deal with exit of child Or to do some action only after the exit of child, then it can use the wait() system call to get the status of child process.