fork, wait and exec calls

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

  • 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 <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.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容