fork, wait and exec calls

fork()

The fork() system call is used to create a new process.

Here're the sample codes.

#include 
#include 

int main(){
    printf("This codes runs before fork() method is called\n");
    int rc = fork();
    if (rc < 0) printf("Error occurred when calling fork()\n");
    else if (rc == 0) printf("This is the child process (pid : %d)\n", (int) getpid());
    else printf("This is the parent process of %d (pid : %d)\n", rc, (int) getpid());
    return 0;
}

If we run the codes in bash

ATWs-MacBook-Pro:os ATW$ ./a.out 
This codes runs before fork() method is called
This is the parent process of 18153 (pid : 18152)
This is the child process (pid : 18153)

Firstly, we need to know what does fork() returns. It returns

  • the PID of the child when it's a parent process
  • 0 when it's a created child process
  • a negative number when errors occurred running fork()

Intuitively, we can notice that fork() will run a copy of parent process. But why codes before fork() was not executed? This is because fork copies the current status of the parent process.

Note the output is not deterministic, i.e. the order is not certain. The CPU scheduler will determin which process runs at a given moment in time.

wait()

#include 
#include 
#include 

int main(){
    printf("This codes runs before fork() method is called\n");
    int rc = fork();
    if (rc < 0) printf("Error occurred when calling fork()\n");
    else if (rc == 0) printf("This is the child process (pid : %d)\n", (int) getpid());
    else {
        int wc = wait(NULL);
        printf("This is the parent process of %d (wc : %d) (pid : %d)\n", rc, wc, (int) getpid());
    }
    return 0;
}

Run it in bash

ATWs-MacBook-Pro:os ATW$ ./a.out 
This codes runs before fork() method is called
This is the child process (pid : 19926)
This is the parent process of 19926 (wc : 19926) (pid : 19925)

In this example, wait() delays the parent execution so child process would run first. This output is deterministic.

exec()

#include 
#include 
#include 
#include 

int main(){
    printf("This codes runs before fork() method is called\n");
    int rc = fork();
    if (rc < 0) printf("Error occurred when calling fork()\n");
    else if (rc == 0){
        printf("This is the child process (pid : %d)\n", (int) getpid());
        char *myargs[3];
        myargs[0] = strdup("wc"); //strdup() simply copies string, wc means wordcounter
        myargs[1] = strdup("p1.c"); // argument : file to count
        myargs[2] = NULL; // end of array
        execvp(myargs[0], myargs);
        printf("This should NOT be printed.\n");
    } 
    else {
        int wc = wait(NULL);
        printf("This is the parent process of %d (wc : %d) (pid : %d)\n", rc, wc, (int) getpid());
    }
    return 0;
}

Run it in bash

ATWs-MacBook-Pro:os ATW$ ./a.out 
This codes runs before fork() method is called
This is the child process (pid : 21341)
      23      92     685 p1.c
This is the parent process of 21341 (wc : 21341) (pid : 21340)

The execvp() is a counting program that tells us how many lines, words and bytes are found in the file.

Why it's cool?

Consider a shell, it's a running process. It shows you a prompt and wait for your input. It fork() a program when you type something. Using exec() to run the program and wait() for the end of execution.

你可能感兴趣的:(fork, wait and exec calls)