美文网首页
fork, wait and exec calls

fork, wait and exec calls

作者: Tirex | 来源:发表于2016-11-09 11:11 被阅读0次

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.

相关文章

网友评论

      本文标题:fork, wait and exec calls

      本文链接:https://www.haomeiwen.com/subject/ibbzuttx.html