• Loading
    • How To Do Process Creation And Termination In UNIX?

      Process Creation And Termination
      You create a new process in Unix by calling the fork() system function. When called, this function splits the current process into two processes, parent and child. A call to the fork() system function creates copy of all the memory pages used by the original process. As a result, both the parent and the child processes have the same image in memory. The return value of the fork() function in the parent process is the process ID (PID) of the child process. In the child process, it returns zero. If the call to the fork() system function fails, no new process is created and the fork() system function returns -1.

      An important feature to note about a process is that when a process is terminated, it is not completely removed from the system. A small part of the process waits to obtain the attention of the parent process. This part contains the value returned by the child process and information related to the child process. After a parent process forks into a child process, the parent process has to wait for the child process to terminate. This waiting mechanism of the parent process removes all the parts of the child process. An exception to this mechanism is possible if the parent process ignores the SIGCLD signal. Then, the parent process does not wait for the child process to terminate. This is a system-specific mechanism. You can implement this mechanism using the C programming language as shown in next section.

      Implementation of the fork() and the signal() System Functions
      Code:
      #include <unistd.h>/* This header file defines the fork() function.*/
      #include <signal.h>
      /*This header file defines various signals and their related functions.*/
      int main()
      {
      /*This call to signal() function ignores the SIGCLD signal.*/
           signal(SIGCLD, SIG_IGN);
           /* Code may go here   */
              
           fork();fork();fork();fork();
         /*sanky!, sanky!, sanky!, sanky!*/
         /The corresponding messages with the fork() system function indicate that the parent process is not waiting. */
           return 0;/*Ensures normal termination*/
      }
      When a child process is terminated and the parent process does not wait, the child process is assigned a <defunct> state. At any point in time, you can view the status of this child process by typing the ps command at the command prompt.

      When the parent process is terminated before it waits for the child process, the child becomes the parent to the init() process. If the child is in a <defunct> state, a problem arises. The original parent process cannot wait further because the child process is terminated. This causes a problem for the init() process because it cannot wait for these defunct processes. In some systems, the init() process periodically destroys all its defunct processes. In other systems, the init() process does not become the parent of any defunct process. This problem can be solved by ensuring that the parent process either ignores the SIGCLD signal or waits for all the children that it forks.

      The Use of the fork() System Function
      Code:
      #include <stdio.h> /* This defines printf() function */
      /*This header file defines the fork() system function, and the variable pid_t*/
      #include <unistd.h>
      /*This header file defines the variable pid_t*/
      #include <sys/types.h>
      /*This header file defines the wait() system function*/
      #include <sys/wait.h>
      /*This header file defines perror() system function*/
      #include <errno.h>
      
      int main()
      {
      /*The variable, chldpid stores the PID of the child process*/
           pid_t chldpid;
      /*The variable, chldstatus contains the exit status of the child process*/
           int chldstatus;
      /*This call to fork() function forks a child process*/
           chldpid = fork();
      /* This switch statement checks the fork() system function for its success and failure*/
           switch (chldpid)
           {
                case -1:   
                      perror("fork failed");  /* prints
      a system-defined error message */
                      exit(1); /* This ensures normal termination.*/
                case 0:        /*When the call to fork()
      function succeeds, child process starts executing*/
      /*This prints a message to the screen*/
                      printf("Hello child!\n");
      /*This call to exit() function ends the child process but the parent process remains active.*/
                      exit(0);
      /*When the return value of the fork() system function is
      other than 0 or –1*/
                default:
      /*When the call to fork()succeeds, the execution of the parent process begins.*/
      /*This call to wait() function keeps the parent process waiting until the child process terminates.*/
                      wait(&chldstatus);
           }
      /*Parent process code may continue here*/
               return 0;
      }

      In the above code, the perror() system function sends an error message to the terminal, and the wait() system function waits for the child process to terminate. The wait() system function also stores the termination status of the child process in the variable, chldstatus. The fork() system function also copies a memory area called the User Area (U-Area). Apart from containing the information related to the process, this U-Area also contains the file descriptor of the process. This allows the child process returned by the fork() function call to inherit all the open files in the parent process. When one of the two processes reads from any of the open files, the read/write pointer is moved for both the parent and the child processes. If a file is opened after the fork() system function, the file is not shared by both the processes. When one process closes a shared file, the file remains open in the other process.

      After a process is created, it has to be terminated. There are two methods of process termination. In the first method, the parent process terminates before the child process. In the second method, the child process terminates before the parent process. The duration between the termination of the child process and the acknowledgement of its termination by the parent process is called zombie. You must write the code for the parent process in such a way that it does not allow the child process to remain in the zombie state endlessly.

      The parent process acknowledges the termination of the child process by calling the wait() system function. When a call to the wait() system function is made, the process in which the wait() function is called is suspended. If there is a zombie child process, the wait() function returns the termination status of that process. When the parent process waits for the termination of the child process, it does not perform any operations. This can be avoided by using signals. When a child process is terminated, the OS sends a SIGCLD signal to the parent of the child process. The parent process then receives an asynchronous notice with the help of the signal handler.

      Using A Signal Handler
      Code:
      #include <stdio.h>     /*This includes standard I/O functions*/
      #include <unistd.h>    /*This defines the system function, fork()*/
      #include <sys/types.h> /*This defines the variable pid_t*/
      #include <sys/wait.h>  /*This defines the system function, wait()*/
      #include <signal.h>    /*This defines the system function signal() */
      
      /* This function defines the code for the signal handler.*/
      void holdchld(int sig_num)
      {
          int chldstatus; /*This stores the status of the child process.*/
          wait(&chldstatus); /*This waits for the child process to terminate.*/
          printf("child process terminated \n"); 
      }
      int main()
      {
      ........./*Some code....*/
           /*Calls the signal() function*/
           signal(SIGCHLD, holdchld);
           /*Code from here forks the child process */
          int chldpid;
          int ctr;
          chldpid = fork();
          switch (chldpid)
          {
              case -1:         
                  perror("fork() system functionfails");
                  exit(1);
              case 0:          
                  printf("Hi Sanky!\n");
                  sleep(10);    /* Sleeps for 10 seconds */
                  exit(0);
              default:         
                  break;
          }/*End of the switch block*/
          
          for (ctr=0; ctr<10; ctr++)
          {
              printf("%d\n", ctr);
              sleep(3);    /* Sleeps for three seconds */
          }
      }/*End of main() function*/
      In the above code, a signal handler is defined, which calls the holdchld() function when it receives a SIGCHLD signal. The fork() system function is called to spawn a child process. When the child process calls the exit() function, a CHLD signal is sent by the system to the parent process. At this point, the execution of the parent process is interrupted and it invokes the CHLD signal handler, holdchld(). The wait() system function in the parent process causes the child process to be removed from the system. At the end, the signal handler is returned, and the parent process continues its execution.
    • Currently Active UsersCurrently Active Users

      There are currently 73 users online. 4 members and 69 guests

      Most users ever online was 323, 11-23-2011 at 07:47 AM.

      1. airncnimxkl,
      2. airnqpzarcl,
      3. snehil2529,
      4. vbairmaclsho