User mode process / thread creation fork / VFORK / pthread_ create

Time:2021-10-28

User mode protocol stack trilogy UIO, data frame, protocol stack
100 lines of code to handle the user state protocol stack
Write a user state network protocol stack to instantly improve your network skills
Linux c + + background server development architect free learning address

fork

After the fork function successfully creates a child process, the parent process returns the PID of the child process and the child process returns 0. The specific description is as follows:
The return value of fork is – 1, which means that the child process creation failed
The return value of fork is 0, which means that the child process is successfully created. This branch is the running logic of the child process
The return value of fork is greater than 0. This branch is the running logic of the parent process, and the return value is equal to the PID of the child process
Let’s take a look at the example of creating a sub process through fork system call:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
 
int main()
{
   pid_t pid = fork();
 
   if(pid == -1){
       printf("create child process failed!\n");
       return -1;
   }else if(pid == 0){
       printf("This is child process!\n");
   }else{
       printf("This is parent process!\n");
       printf("parent process pid = %d\n",getpid());
       printf("child process pid = %d\n",pid);
   }
 
   getchar();
 
   return 0;
}

Operation results:

$ ./a.out
This is parent process!
parent process pid = 25483
child process pid = 25484
This is child process!

From the above running results, the PID of the child process is 25484 and the PID of the parent process is 25483.
When the memory page shortage exception was introduced earlier, it was mentioned that copy cow on write is a technology to delay or avoid copying data. It is mainly used in the fork system call. When the fork is executed to create a new child process, the kernel does not need to copy the entire process address space of the parent process to the child process, but allows the parent process and the child process to share the same copy. Only when writing, Data will be copied. Let’s use a simple example to describe:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int peter = 10;

int main()
{
  pid_t pid = fork();

  if(pid == -1){
      printf("create child process failed!\n");
      return -1;
  }else if(pid == 0){
      printf("This is child process, peter = %d!\n", peter);
      peter = 100;
      printf("After child process modify peter = %d\n", peter);
  }else{
      printf("This is parent process = %d!\n", peter);
  }

  getchar();

  return 0;
}

Execution results:

$ ./a.out
This is parent process = 10!
This is child process, peter = 10!
After child process modify peter = 100

It can be seen from the running results that no matter how the child process modifies the value of Peter, the parent process always sees its own share.
User mode process / thread creation fork / VFORK / pthread_ create

vfork

Next, let’s use VFORK to create child processes:

#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int peter = 10;

int main()
{
  pid_t pid = vfork();

  if(pid == -1){
      printf("create child process failed!\n");
      return -1;
  }else if(pid == 0){
      printf("This is child process, peter = %d!\n", peter);
      peter = 100;
      printf("After child process modify peter = %d\n", peter);
      exit(0);
  }else{
      printf("This is parent process = %d!\n", peter);
  }

  getchar();

  return 0;
}

Operation results:

$ ./a.out
This is child process, peter = 10!
After child process modify peter = 100
This is parent process = 100!

It can be seen from the running results that when the child process modifies Peter = 100, the value of printed Peter in the parent process is also 100.
User mode process / thread creation fork / VFORK / pthread_ create

[article benefits]: Xiaobian has sorted out some learning books and video materials that I think are better. They are shared in the group file. If necessary, you can add them yourself!~Click join(self access required)
User mode process / thread creation fork / VFORK / pthread_ create

pthread_create
Now we know that there are two ways to create a process: fork and VFORK. What about creating threads?
The thread creation interface is pthread_ create:

#include <pthread.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/syscall.h>

int peter = 10;

static pid_t gettid(void)
{
 return syscall(SYS_gettid);
}

static void* thread_call(void* arg)
{
 peter = 100;
 printf("create thread success!\n");
 printf("thread_call pid = %d, tid = %d, peter = %d\n", getpid(), gettid(), peter);
 return NULL;
}

int main()
{
 int ret;
 pthread_t thread;

 ret = pthread_create(&thread, NULL, thread_call, NULL);
 if(ret == -1)
     printf("create thread faild!\n");

 ret = pthread_join(thread, NULL);
 if(ret == -1)
     printf("pthread join failed!\n");

 printf("process pid = %d, tid = %d, peter = %d\n", getpid(), gettid(), peter);

 return ret;
}

Operation results:

$ ./a.out
create thread success!
thread_call pid = 9719, tid = 9720, peter = 100
process pid = 9719, tid = 9719, peter = 100

From the above results, we can see that the PID of process and thread are the same. When the thread modifies Peter = 100, the value of printed Peter in the parent process is also 100.

General drawing of process thread creation
The above describes the methods of creating processes and threads in user mode, as well as the characteristics of each method. The underlying implementation essence will be explained in detail later. Here is the relationship between the three. It can be seen that all three will eventually call do_ Fork implementation.

However, there is no concept of process thread in the kernel state, and only task is recognized in the kernel_ Struct structure, as long as it is a task_ Struct structure can participate in scheduling.

Recommended Today

Swift advanced (XV) extension

The extension in swift is somewhat similar to the category in OC Extension can beenumeration、structural morphology、class、agreementAdd new features□ you can add methods, calculation attributes, subscripts, (convenient) initializers, nested types, protocols, etc What extensions can’t do:□ original functions cannot be overwritten□ you cannot add storage attributes or add attribute observers to existing attributes□ cannot add parent […]