Process control - fork and exec

Process control - fork and exec

fork

fork is the only way to spawn new processes in UNIX systems

The role of fork is to copy the current process, generate a child process, and the child process continues to execute from the fork position. The characteristics of the fork function can be summarized as "call once, return twice", call once in the parent process, and return once in each of the parent process and the child process. Fork is like a fork, which turns the program executed sequentially into two branches, which are executed concurrently .

The fork call fails and returns -1, the return value of fork in the child process is 0, and the return value of fork in the parent process is the id of the child process

Usage of fork

  1. A process creates a copy of itself, so that each copy can process one of its own operations while the other copy performs other tasks. This is a typical usage of a web server;
  2. A process wants to execute another program. Since the only way to create a new process is to call fork, the process first calls fork to create a copy of itself, and then the other copy (usually a child process) calls exec to replace itself with the new program. This is typical usage of programs like shells;

After the parent process calls fork, use a variable to record the return value, that is, the pid of the child process, otherwise the child process will not be found, and the child process can find the parent process through getppid.

#include <stdio.h>
#include <unistd.h>

int main()
{
    pid_t pid;
    pid = fork();
    if(-1 == pid){
        perror("fork");
        exit(1);
    }
    if(0 == pid){
        printf("i am parent, %d\n",getpid());
    }
    else if(pid >0){
        printf("i am child, %d\n",getpid());
    }

}

i am child, 5909
[root@192 ~]# i am parent, 5910

copy-on-write

Under normal circumstances, the child process and the parent process share the address space. When one party needs to modify the data content, a copy is made to each (copy the page table of the modified data). Since the code segment will definitely not change, the code segment always enjoys the same block of address space.

int g_val = 0;

int main()
{
    pid_t pid = fork();
    if(pid == 0){
        //子进程
        g_val = 100;
        printf("child val=%d, &val = %d\n", g_val, &g_val);
    }
    else{
        sleep(3);
        printf("parent val=%d, &val = %d\n", g_val, &g_val);
    }
}

child val=100, &val = 134518596
parent val=0, &val = 134518596

Operation result description:
1. The contents of the two variables are different, indicating that each process has a variable
2. The addresses of the two variables are the same, indicating that they are virtual addresses

vfork

  1. It is guaranteed that the child process executes before the parent process
  2. After the child process is executed, if exit is not used, the main stack frame will be modified, causing the parent process to segfault.
  3. There is no copy-on-write in vfork, which is efficient
  4. Usually don't use vfork, there are problems
int main()
{
    int  r = 10;
    pid_t pid = vfork();
    if(pid == 0){
        sleep(1);
        r = 1;
        printf("child  %d\n", r);
        exit(0);
    }
    else{
        printf("parent %d\n", r);
    }
}

child 1
parent 1

exec

After creating a child process with fork, it executes the same program as the parent process (but it may execute a different code branch). The child process often calls an exec function to execute another program. Calling exec does not create a new process, so the id of the process does not change before and after calling exec.

exec implements redirection

After calling exec, the original open file descriptor is still open.

Explanation: In Unix/Linux, the parent process calls fork to create a child process, and the file descriptor opened by the parent process will be copied to the child process, so that the child process shares the open file with the parent process through the file descriptor copied by the parent process. file entry.

And exec will inherit the file descriptor of the child process, that is to say, the file stream opened in the child process can be used in the new process after exec.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325899332&siteId=291194637