fork, wait and exec calls

2016-11-09  本文已影响0人  Tirex

fork()

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

Here're the sample codes.

#include <stdio.h>
#include <stdlib.h>

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

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 <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>

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 <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <string.h>

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.

上一篇 下一篇

猜你喜欢

热点阅读