Process API Study Notes

INTERLUDE: PROCESS API

Introduction to Interludes

  • Interludes cover practical aspects of systems, focusing on operating system APIs and their usage.

  • Working with practical skills is emphasized, as these are often valued in the job market.

Overview of Process Creation in UNIX Systems

  • Discusses process creation using the fork() and exec() system calls in UNIX systems.

  • Introduces the wait() system call for processes wishing to wait for the completion of child processes.

  • Central question: How to create and control processes and design interfaces that are user-friendly and useful.

5.1 The fork() System Call

  • Definition: The fork() system call is utilized to create a new process.

  • Forking is described as a strange routine that creates an almost exact copy of the calling process.

  • Execution Example:

    • A typical structure of a program invoking fork:

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    main(int argc, char *argv[]) {
        printf("hello world (pid: %d)\n", (int) getpid());
        int rc = fork();
        if (rc < 0) {
            fprintf(stderr, "fork failed\n");
            exit(1);
        } else if (rc == 0) {
            // child (new process)
        } else {
            printf("hello, I am child (pid: %d)\n", (int) getpid());
            printf("hello, I am parent of %d (pid: %d)\n", rc, (int) getpid());
        }
        return 0;
    }
    
  • The program prints its PID (Process Identifier). Initial message shows the parent process.

  • After calling fork(), both the parent and child processes execute, but the child will return a value of 0 while the parent will receive the PID of the child (rc).

5.2 Understanding Fork Output Non-Determinism

  • Output example and its variability:

    • Output order is non-deterministic; either child or parent may print first based on CPU scheduling:

    • Example Output 1:
      prompt/pl hello world (pid: 29146) hello, I am parent of 29147 (pid: 29146) hello, I am child (pid: 29147) prompt>

    • Example Output 2:
      prompt> hello world (pid: 29146) hello, I am child (pid: 29147) hello, I am parent of 29147 (pid: 29146) prompt>

  • The CPU scheduler determines which process runs at any moment, leading to potential scenarios in the order of execution.

Adding wait() System Call

  • Purpose of wait(): To allow the parent process to wait for the completion of a child process.

  • Modified Output Determinism: After adding wait(), the parent's output can be made deterministic.

  • Example Program with wait():

  int wc = wait(NULL);
  printf("hello, I am parent of %d (wc: %d) (pid: %d)\n", rc, wc, (int) getpid());
  • The parent will always complete its execution after the child completes, ensuring consistent output.

5.3 The exec() System Call

  • Definition: The exec() system call is utilized to run a different program than the one currently executing.

  • Execution Example: Running wc Using execvp():

    • Here’s how it transforms process execution:

  // child: execute different program
  char *myargs[3];
  myargs[0] = strdup("wc");
  myargs[1] = strdup("p3.c"); // argument: file to count
  myargs[2] = NULL; // marks end of array
  execvp(myargs[0], myargs);
  • After calling exec(), the previous program execution is replaced, meaning if exec() is successful, it does not return control back to the previous program.

5.4 Motivating the API

  • Rationale for Separation of fork() and exec(): Permits additional actions to be performed after the fork before the exec call, allowing for modifications to child process environment.

  • Example: A shell uses fork() and exec() to run commands.

  • Output Redirection Example: Redirecting output to a file using:

  prompt wc p3.c > newfile.txt
  • Process: The shell closes STDOUT, opens a file, and any output from the wc program is directed to the file.

5.5 Other Parts of the API

  • Other important system calls include:

    • kill(): Sends signals to processes for management such as sleep or termination.

    • Process observation tools like ps and top to monitor active processes and resource usage.

5.6 Summary

  • The primary APIs for UNIX process creation include fork(), exec(), and wait().

  • A deeper understanding of these calls and related concepts can be found in resources like W. Richard Stevens's books.