parent process does not wait for the child process (c code) - c

char array[ARRAY_SIZE];
void child_process_routine(){
int j;
for(j = 0;j<ARRAY_SIZE;j++)
array[j]='d';
}
main()
{
pid_t child_pid;
int i;
for(i = 0;i<ARRAY_SIZE;i++)
array[i]='c';
child_pid = fork();
switch (child_pid) {
case -1:
perror("error");
exit(1);
case 0:
child_process_routine();
exit(0);
default:
wait(NULL);
}
print_array(array);
}
can you explain me why the parent process does not wait for the child process and this gives me the output " cccccc " again? it was changed in the child process into " dddddd "
what does wait(NULL) even do?
how does it supposed to know it should wait for the child process?

The parent process is waiting for the child process.
The child is not a thread, it is a completely different process with its own unique PID and the parent as its Parent PID. The child and the parent do not share the same array, the child has its own copy since it is a different process (not a thread of the same process). So when you set the array to 'd' in the child it does not affect the array in the parent process.
Try putting a sleep(20) in the child process flow right before it exits, and a printf() just before the parent wait(). You will see that your application pauses as the parent is waiting for the child to finish.

fork() creates a different process but parent share the same process context.
but if you try to change anything in the stack segment of parent it makes a copy of that and creates a separate stack for child process, but all the resources like data segment, code segment, etc are not copied for child process. They both share it.
This copying on changing the data after fork is called "copy on write"
Parent process is waiting for child process to finish. But its printig for both parent and child separately and different data for both

Related

How do you kill zombie process using wait()

I have this code that requires a parent to fork 3 children.
How do you know (and) where to put the "wait()" statement to kill
zombie processes?
What is the command to view zombie processes if you have Linux
virtual box?
main(){
pid_t child;
printf("-----------------------------------\n");
about("Parent");
printf("Now .. Forking !!\n");
child = fork();
int i=0;
for (i=0; i<3; i++){
if (child < 0) {
perror ("Unable to fork");
break;
}
else if (child == 0){
printf ("creating child #%d\n", (i+1));
about ("Child");
break;
}
else{
child = fork();
}
}
}
void about(char * msg){
pid_t me;
pid_t oldone;
me = getpid();
oldone = getppid();
printf("***[%s] PID = %d PPID = %d.\n", msg, me, oldone);
}
How do you know (and) where to put the "wait()" statement to kill
zombie processes?
If your parent spawns only a small, fixed number of children; does not care when or whether they stop, resume, or finish; and itself exits quickly, then you do not need to use wait() or waitpid() to clean up the child processes. The init process (pid 1) takes responsibility for orphaned child processes, and will clean them up when they finish.
Under any other circumstances, however, you must wait() for child processes. Doing so frees up resources, ensures that the child has finished, and allows you to obtain the child's exit status. Via waitpid() you can also be notified when a child is stopped or resumed by a signal, if you so wish.
As for where to perform the wait,
You must ensure that only the parent wait()s.
You should wait at or before the earliest point where you need the child to have finished (but not before forking), OR
if you don't care when or whether the child finishes, but you need to clean up resources, then you can periodically call waitpid(-1, NULL, WNOHANG) to collect a zombie child if there is one, without blocking if there isn't any.
In particular, you must not wait() (unconditionally) immediately after fork()ing because parent and child run the same code. You must use the return value of fork() to determine whether you are in the child (return value == 0), or in the parent (any other return value). Furthermore, the parent must wait() only if forking was successful, in which case fork() returns the child's pid, which is always greater than zero. A return value less than zero indicates failure to fork.
Your program doesn't really need to wait() because it spawns exactly four (not three) children, then exits. However, if you wanted the parent to have at most one live child at any time, then you could write it like this:
int main() {
pid_t child;
int i;
printf("-----------------------------------\n");
about("Parent");
for (i = 0; i < 3; i++) {
printf("Now .. Forking !!\n");
child = fork();
if (child < 0) {
perror ("Unable to fork");
break;
} else if (child == 0) {
printf ("In child #%d\n", (i+1));
about ("Child");
break;
} else {
/* in parent */
if (waitpid(child, NULL, 0) < 0) {
perror("Failed to collect child process");
break;
}
}
}
return 0;
}
If the parent exits before one or more of its children, which can happen if it does not wait, then the child will thereafter see its parent process being pid 1.
Others have already answered how to get a zombie process list via th ps command. You may also be able to see zombies via top. With your original code you are unlikely to catch a glimpse of zombies, however, because the parent process exits very quickly, and init will then clean up the zombies it leaves behind.
How do you know (and) where to put the "wait()" statement to kill
zombie processes?
You can use wait() anywhere in the parent process, and when the child process terminates it'll be removed from the system. Where to put it is up to you, in your specific case you probably want to put it immediately after the child = fork(); line so that the parent process won't resume its execution until its child has exited.
What is the command to view zombie processes if you have Linux virtual box?
You can use the ps aux command to view all processes in the system (including zombie processes), and the STAT column will be equal to Z if the process is a zombie. An example output would be:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
daniel 1000 0.0 0.0 0 0 ?? Z 17:15 0:00 command
How do you know (and) where to put the "wait()" statement to kill
zombie processes?
You can register a signal handler for SIGCHLD that sets a global volatile sig_atomic_t flag = 0 variable to 1. Then, at some convenient place in your program, test whether flag is set to 1, and, if so, set it back to 0 and afterwards (for otherwise you might miss a signal) call waitpid(-1, NULL, WNOHANG) in a loop until it tells you that no more processes are to be waited for. Note that the signal will interrupt system calls with EINTR, which is a good condition to check for the value of flag. If you use an indefinitely blocking system call like select(), you might want to specify a timeout after which you check for flag, since otherwise you might miss a signal that was raised after your last waitpid() call but before entering the indefinitely blocking system call. An alternative to this kludge is to use pselect().
Use:
ps -e -opid,ppid,pgid,stat,etime,cmd | grep defunct
to see your zombies, also the ppid and pgid to see the parent ID and process group ID. The etime to see the elapsed (cpu) time your zombie has been alive. The parent ID is useful to send custom signals to the parent process.
If the parent process is right coded to catch and handle the SIGCHLD signal, and to what expected (i.e., wait/reap the zombies), then you can submit:
kill -CHLD <parent_pid>
to tell the parent to reap all their zombies.

Why is my parent process not waiting the second time? C/Unix

So, what I am trying to do is create a child process, have it execute execl and run ls. Then after ls is done, create another child process and have it run a cat command on a file. The second wait(pid) does not seem to wait for the second child process to complete before finishing. here is my code and output
#include <fcntl.h>
int main(){
int pid;
printf("In parent process, creating child now...\n");
pid = fork();
if (pid==0){
printf("Now in child process...\n");
execl("/bin/ls","ls","-l",(char*)0);
}
wait(pid);
printf("ls child process complete\n");
printf("in parent process\n");
printf("Creating another child process\n");
pid=fork();
if(pid==0){
execl("/bin/cat","cat","f1",(char*)0);
}
wait(pid);
return 0;
}
Here is my output
In parent process, creating child now...
Now in child process...
"Contents of ls"
ls child process complete
in parent process
creating another child process
[username#host ~]$ "Contents of file" *cursor*
the parent process seems to finish before the second child is complete. There is only 1 child existing at a time. The "Contents of file" are supposed to appear before the [username#host ~]$ prompt. I think i am misplacing a wait or wrong pid assignment or something. Thanks in advance!
The argument to wait() is not a PID. It's a pointer to an int where the exit status will be stored. You're passing an integer where a pointer is needed, which means:
The program might crash or corrupt some unrelated memory location as soon as you call wait. Its behavior after that point is unpredictable.
You need to enable more compiler warnings and pay attention to them.
Although the Cat process may have finished the disk cache may still be holding the results... Instead of waiting for cat to complete wait until the lock on the file is released.

Linux Fork: pid reuse

I wrote the following program to understand the way fork works when called without wait() or waitpid().
int main()
{
pid_t childpid;
int retval = 0;
int i;
while(1){
//usleep(1);
childpid = fork();
if (childpid >= 0)
{
i++;
if (childpid == 0)
{
exit(retval);
}
else
{
//printf("childpid is %d\n", childpid);
}
}
else
{
printf("total no. of processes created = %d\n", i);
perror("fork");
exit(0);
}
}
}
Here's the output I get->
total no. of processes created = 64901
fork: Cannot allocate memory
I expected the program to go on as I'm exiting the child process instantly and fork() should reuse the pids after pid > pid_max. Why doesn't this happen?
The exited child processes do remain in the process table as zombies. Zombie processes exist until their parent calls wait or waitpid to obtain their exit status. Also, the corresponding process id is kept, to prevent other newly created processes of duplicating it.
In your case, the process table becomes too large and the system rejects the creation of new processes.
Forking processes and then not retrieving their exit status can be regarded as a resource leak. When the parent exits, they will be adopted by the init process and then reaped, but if the parent stays alive for too long, there is no way for the system to just remove some of the zombies, because it is assumed that the parent should get interested in them at some point via wait or waitpid.
Child processes also hold some resource like memory. But they are not released because parent process can not process SIGCHLD signal, which will be sent by child processes when they exit.
Those child processes will become zombie.
You can use "ps -aux" to dump those fd.

Parent and child of fork() in C

Since each process is doing its own thing, which to me feels more like a "brothers/sisters" relationship. Is there a specific reason behind calling them parent process and child process?
Also, is it true that the parent process always run before the child process?
The parent owns the process group and thus spawns and reaps the children. Usually this process does a little bit of administrative work, while the children act as peers and siblings.
The naming is just convention for describing which process spawned the other, though.
The parent process and child process does the work based on your code but not because of parent or child relationship. When you execute fork() in the main thread it will create a child process, here the fork returns a value which is different in parent process and child process which can be used to differentiate the work of parent and child processes accordingly.
fork() always return pid of child in parent process and 0 in child process.
Coming to your second question it always depends on the scheduler as soon as the fork() is called and we cannot predict which process gets to run first after fork() function call.
Is there a specific reason behind calling them parent process and child process?
Well, since it one process (the parent) that creates the second one (the child), that might be the reasoning for the naming.
Also, is it true that the parent process always run before the child process?
The short answer. Nope.
I have been using this in all of my C-code
pid_t pid = fork();
if(pid == 0){ // child
// Child stuff
}else{ // parent
// Parent stuff
}
You might also want to use the
waitpid(pid, NULL, 0);
Parents are always before child. Sort and sweet!!!
fork() creates a copy of the current process which is a part of the process control group. The new process is subordinate to the originating process, for example when a child process dies, SIGCHLD is sent to the parent. Also, the clone is an inferior copy: for instance, any stored getpid() results will be inaccurate in the child; the child has a different parentid, the child has copies of the parent's file descriptors, and has independent resource usage counters.
The parent process, then, is always the one that made the call to fork(), if that's what you mean by run first. If you mean "will the scheduler always give the parent process slices first" then the answer is no.
See: http://gauss.ececs.uc.edu/Courses/c694/lectures/ForksThreads/forks.html, http://linux.die.net/man/2/fork
#include <stdio.h>
#include <unistd.h>
int main(int argc, const char* argv[])
{
pid_t otherPid;
printf("parent pid = %u\n", getpid());
otherPid = fork();
// in the parent, otherPid = the child's (new) process ID
// in the child, otherPid = 0.
switch (otherPid) {
case -1:
printf("Fork failed: %d\n", errno);
return errno;
break;
case 0: // child
sleep(2);
printf("child: my pid is %u\n", getpid());
break;
default:
printf("parent: pid is %u, child should have %u\n", getpid(), otherPid);
sleep(3);
break;
}
return 0;
}

Get child process id of already running process

I'm calling an external program (via pty.js in node) that when it runs it spawns a child process. When the parent process finishes it leaves the child running for quit some time (orphan). I can get the id of the parent process, but would like to get the id of the child that is spawned so I can kill it when the parent quits.
I don't believe there is any way in node to achieve this, so is there anything in C that allows you to get the id of a child, knowing only the parent id. Everything I have found so far relates to getting the child id from the fork() but the fork took place in the external program.
Alternatively I guess I could make a call to ps or pstree / something similar and parse the output but feels like a bit of a hack.
EDIT
It's not nice but I've come up with this so far:
#include <limits.h>
#include <stdio.h>
int main(int argc, char *argv[]) {
int id = atoi(argv[1]);
int i;
for(i = 0; i < INT_MAX; i++) {
if(i != id && getpgid(i) == id) {
printf("Process %d, is a child of %d", i, id);
break;
}
}
}
In node.js you can do it via child_process library. There is a pid member function that returns the spawned child's pid. E.g.
var spawn = require('child_process').spawn,
grep = spawn('grep', ['ssh']);
console.log('Spawned child pid: ' + grep.pid);
grep.stdin.end();
You can also kill the child process with kill.
The pty.js does a fork with a pseudo terminal, which is useful if emulating terminal. Otherwise you should use child_process to spawn/fork new processes.
If you can add this code at the end of parent process :
int i ;
while(1)
{
i = wait();//wait child exit
if(i == -1)//if there is no child process
break;
}
If you can't . Then you need do nothing!
Here is the problem:
If the parent process finished but the children process didn't, those children process called :"orphan process" NOT "zombie". A "zombie process" means a child process finished while the patent process still runs, and the parent process didn't handle the child process's aftermath.
Since system will set "init" become the parent of all "orphan process".The init process will deal with everything . So you need do nothing.!!

Resources