Working With Wait() In UNIX

Wait , Wait p id ()

Wait for process to change state

# include <sys / types.h>

# include <sys / wait.h>

P id – t Wait  (int * status)

P id – t Wait (p id – t p id, int * status , int options);

Int wait id (id type  id type, id – t id, sigin to – t * in fop, int options);

 

Wait ()

The wait () system call suspends executor of the current . process until one of its children terminates the call wait (& status ) is equivalent to

Wait p id (- 1, & status , 0);

The wait p id () system call  suspends execution  of the current  a  child  specified by p id argument has changed state , by default  wait p id () waits only for terminated children . but this behavior is modified via the options argument as described below

 

< -1  -   meaning wait for any child process  whose process group ID is equal to the absolute value of P id

 

-1     -     meaning wait for any child process

 

0     -     meaning wait for any child process whose process group ID is equal to that of calling process

 

>0   -     meaning wait for the child whose process ID is equal to value of Pid

 

Wait ()   -   is only for parent to wait and not child to wait () for parent  & exited value is calls. wait   for child  exd, this a voids child to be

 

Wait ()  -   on success, returns the process ID of the terminated child , on error , -1 is returned.

 

Wait P id() -  on  Success , returns the process ID of the child whose state has changed ; on error , -1 is        returned if ‘WNO HAN &’  was specified and no child specified by p id has yet changed state then o is returned .

 

Wait id ()    -      Returns  0 on success or if WNO HAN &  Was specified and no child specified by id has yet changed state ; on error , -1 is returned.

 

Errors

ECHID    -     (for wait ())  the calling process does not have any un waited – for children

 

ECHILD  -   (for  wait p id () or wait id ())

[ The process specified  by p id (wait p id ()) or id type and id  (wait id ()) does not  exits or  is not   a child  of the calling process . (This can happen for one’s own child if the action for SIGCHILD is set to SIG. IGN) ]

 

EINUAL -   The options argument was in valid

 

EINTR   -    WNDHANG was not set and an unblocked signal or a SIGCHILD was caught.

 

Copy – on – Write ()

A separate copy of data will be created , whenever parent/ child modifies the common data.

#include <stdio.h>

#include <stdlib.h>

Int g = 0;

Main ()

{

Int l = 0;

P F (“l & g modified to l= 20, g = 10 globally \n ”);

L = 20;

G= 10;

If (fork () )

{

PF (“Parent : l = %d, g = %d\n”, l ,g);

}

Else

{

PF (“Child  : l = %d, g = %d\n”, l ,g);

L ++;

G++;

PF (“l ++, g++ done in child \ n”);

PF (“child : l + % d, g = %d \n” l , g);

}

}

Output

L = 0, g =0

L & g modified to l = 20, g = 10 globally

Child : l =20, g =10

L++, g ++ done in child

Child : l =21, g =11

Parent : l =20, g =10

 

  • Parent & child share common code
  • For’ Data protection ‘ data modified in one process will not be reflected in another process
  • Data protection in done through ‘ copy – on – write ’

 

So, data modified by in child is not reflected in parent.

 

Name

-exit,  - Exit – terminate the current process

#include <unistd.h>                                                  #include <stdlib.h>

Void – exit (int status )                                                Void – Exit (int status )

 

  • The function - Exit () is equivalent to –exit ()
  • The function – exit () terminates the calling process “immediately” . Any open file descriptors belonging to the process are closed; any children of the process are inherited by process in it, and the process’s parent is sent a SIGCHILD signal
  • The value status is returned to the parent process as the process’s exit status and can be effected using one of the wait () family of calls.

 

Return Value

  • These functions do not return
  • Exit values are in the range of 0 to 255 and any exit value does not effect the process.
  • Exit value is short int of 2 bytes and is collected by wait () function in MSB.

 

#include <stdio. h>

#include <stdlib.h>

Main ()

{

If (fork ())

{

Int  st, ret

Pf(“parent executing \ n”);

Pf(“parent Waiting  \ n”);

Ret = Wait  (& st);

Pf(“child exited with  % d as collected in MSB \ n”, st);

St = st >> 8 ;  // Hence it is shifted  8 Times

Pf(“child exited with  % d \ n”, st);

Pf(“parent about to exit \ n”);

Exit (0);  // this exit value is returned to bash

}

Else

{

Int  t ;

Srand  (get p id ());

T = rand ()  % 10 +1 ;

Sleep (t);

Exit (i);

}

}

 

Output

Parent    executing

Parent     waiting

Child       exited with 256 as collected in MSB

Child      exited with 1

Parent    about to exit

 

W. a. p to input two small integers (in between 1 to 50) from command line create a new process by fork code. The sum of two integers by the child process and print  the result

Note

These should not be any print statement in child

#include <stdio. h>

#include <stdlib.h>

Main  (int argc, char ** arg v)

{

If (arg c ! =3)

{

Pf (“Usage :  ./a.out   <Integer 1>            <Integer 2> ” /n);

Return;

}

If (fork  ())

{

Int st, ret;

Ret = wait (& st);

St = st >>8;

Print F(“Sum = % d /n”, st);

Exit (0);

}

Else

{

Int a, b ;

A = a to I (arg V [1]);

b= a to I (arg V [2]);

exit (a + b);

}

}

 

Output

./a.out   12      14

Sum = 26

 

  1. W. a. p to create three children from common parent & all the children should delay for randomly generated time of 1 to 10 sec. modify the parent such a manner none of child become orphan.

#include <stdio. h>

#include <stdlib.h>

Main ()

{

If (fork ())

{

If (fork ())

{

If (fork ())

{

//parent process

Int st , ret;

PF (“ parent : p id = % d, p pid = % d/n” get p id (), get p id ());

While (ret ! = -1)

{

Ret = wait (& st ),

St >>=8;

If (st = = 1)

PF (“child 1 exited with % d /n ”, st);

If (st = = 2)

PF (“child 2 exited with % d /n ”, st);

If (st = = 3)

PF (“child 3 exited with % d /n ”, st);

}

Exit (0);

}

Else

{

//child 3 process

Int t;

Srand   (get p id ());

T = rand () % 10 +1;

Sleep (t);

PF (“child 3 : p id = % d, p pid = %d \ n ”, get p id (), get p pid ());

Exit (3);

}

}

Else

{

Int t;

Srand   (get p id ());

T = rand () % 10 +1;

Sleep (t);

PF (“child 2 : p id = % d, p pid = %d \ n ”, get p id (), get p pid ());

Exit (2);

}

}

Else

{

//child 1 process

Int t;

Srand   (get p id ());

T = rand () % 10 +1;

Sleep (t);

PF (“child 3 : p id = % d, p pid = %d \ n ”, get p id (), get p pid ());

Exit (1);

}

}

 

OUTPUT

Here no child is exited after execution. Hence no child becomes orphan.

 

(ii) Make  the parent wait  only for 2nd child . If exit states is ‘2’, then wait ()

#include <stdio.h>

#include <stdlib.h>

Main ()

{

If  (fork ())

{

If  (fork ())

{

If  (fork ())

{

//parent process

Int  st, ret;

PF(“Parent : p id = % d, p pid = % d\n ”, get p id (), get p pid ());

While (ret ! =1)

{

Ret = wait (& st)

St>>8;

If (st = = 2)

{

Pf (“child 2 exited with  % d \n ” , st);

Exit (0);

}

Else

{

//child 3 process

Int t ;

Srand (get p id ());

T = rand () % 10 +1;

Sleep (t);

Pf(“Child  : p id = % d, p pid = % d\n ”, get p id (), get p pid ());

Exit (3);

Else

{

//child 2 process

Int t ;

Srand (get p id ());

T = rand () % 10 +1;

Sleep (t);

Pf(“Child  2 : p id = % d, p pid = % d\n ”, get p id (), get p pid ());

}

}

Else

{

//child 1process

Int t ;

Srand (get p id ());

T = rand () % 10 +1;

Sleep (t);

Pf(“Child 1 : p id = % d, p pid = % d\n ”, get p id (), get p pid ());

}

}

 

Output:

Hence is child 2 is executed , then child  1 & child 3 becomes orphan.

Depending on, random generator  of child 2 execution the process that are executed after child 2 becomes orphan.