Fork kernel implementation

Source: Internet
Author: User

Process and thread are two concepts that we usually use. In particular, thread mechanisms are supported by many languages. Some time ago, we mainly demonstrated how to create processes and threads in Linux.ArticleMake a simple analysis on the process of its creation. Make sure that you are correct about the error.

In Linux, a thread is actually a lightweight process, so its implementation is implemented by calling the do_fork function to input different parameters. Let's take a look at these functions:

1 Int Sys_fork ( Struct Pt_regs * Regs)
2 {
3 Return Do_fork (sigchld, regs -> SP, regs, 0 , Null, null );
4 }

1 Int Sys_vfork ( Struct Pt_regs * Regs)
2 {
3 Return Do_fork (clone_vfork | Clone_vm | Sigchld, regs -> SP, regs, 0 ,
4 Null, null );
5 }

 

1 Sys_clone (unsigned Long Clone_flags, unsigned Long Newsp,
2 Void _ User * Parent_tid, Void _ User * Child_tid, Struct Pt_regs * Regs)
3 {
4 If ( ! Newsp)
5 Newsp = Regs -> SP;
6 Return Do_fork (clone_flags, newsp, regs, 0 , Parent_tid, child_tid );
7 }

The aboveCodeThe implementation of the fork () function is not seen. In fact, the execution process of the fork function is roughly like this: normalProgramCall fork () --> library function fork () --> System Call (fork function number) --> Find sys_fork () from function number in sys_call_table () function address --> call sys_fork (), which completes the process of pulling from the user State to the kernel state. Therefore, in fact, the implementation of the fork function is sys_fork.

Similar to the above process, the above functions correspond to fork, vfork, and clone respectively. We can see that they are actually implemented by calling the do_fork function, the input parameters are different. First, let's look at the input parameters. First, let's look at the meanings of these input parameters:

Cloning flags /*
* Cloning flags:
*/
# Define Csignal 0x000000ff/* signal mask to be sent at exit */
# Define Clone_vm 0x00000100/* set if VM shared between processes */
# Define Clone_fs 0x00000200/* set if FS info shared between processes */
# Define Clone_files 0x00000400/* set if open files shared between processes */
# Define Clone_sighand 0x00000800/* Set IF signal handlers and blocked signals shared */
# Define Clone_ptrace 0x00002000/* set if we want to let tracing continue on the child too */
# Define Clone_vfork 0x00004000/* set if the parent wants the child to wake it up on mm_release */
# Define Clone_parent 0x00008000/* set if we want to have the same parent as the cloner */
# Define Clone_thread 0x00010000/* same thread group? */
# Define Clone_newns 0x00020000/* New namespace group? */
# Define Clone_sysvsem 0x00040000/* Share System V sem_undo semantics */
# Define Clone_settls 0x00080000/* Create a New TLS for the child */
# Define Clone_parent_settid 0x00100000/* set the TID in the parent */
# Define Clone_child_cleartid 0x00200000/* clear the TID in the child */
# Define Clone_detached 0x00400000/* unused, ignored */
# Define Clone_untraced 0x00800000/* set if the tracing process can't force clone_ptrace on this clone */
# Define Clone_child_settid 0x01000000/* set the TID in the child */
# Define Clone_stopped 0x02000000/* start in stopped state */
# Define Clone_newuts 0x04000000/* New utsname group? */
# Define Clone_newipc 0x08000000/* New IPCS */
# Define Clone_newuser0 x 10000000/* New User namespace */
# Define Clone_newpid 0x20000000/* New PID namespace */
# Define Clone_newnet 0x40000000/* New Network namespace */
# Define Clone_io 0x80000000/* clone Io context */

Then let's take a look at the specific process of do_fork:

    1. P = copy_process (clone_flags, stack_start, regs, stack_size,
      Child_tidptr, null, trace );
    2. Wake_up_new_task (p, clone_flags );

The first step is to call the copy_process function to copy a process and set the corresponding flag, etc. Next, if copy_process is called successfully, the system will intentionally run the new process, this is because sub-processes generally call the exec () function immediately to execute other tasks, which can avoid overhead caused by replication or, from another perspective, if the parent process is executed first, and the parent process may write data to the address space during execution, the system copies the original data of the parent process for the child process. When the child process is called, it then executes the exec () operation, the system will copy new data for the sub-process. In this way, a "redundant" copy is performed compared to the subprogram execution priority.

From the above analysis, we can see that the implementation of do_fork () mainly relies on copy_process (). This is a set of links, so when we look at the kernel, I think it's a big reason to suddenly jump here and then again. However, I think this is also a major benefit of Linux, because it improves the reusable rows of functions. For example, the implementation of several functions mentioned at the beginning of this article is ultimately implemented through do_fork ().

 

Next let's take a look at the implementation of copy_process:

    1. P = dup_task_struct (current); Create a kernel stack, thread_iofo, and task_struct for the new process. The content of the parent process is completely copied here. So far, there is no difference between a parent process and a child process.
    2. Check whether all processes have exceeded the maximum number of processes specified by the system. If not, set the initial value in the process description, the parent process and child process start to differentiate.
    3. Set the sub-process status to not be task_uninterruptible, so that the process cannot be put into operation now, because there are still a lot of signs, data, and so on are not set.
    4. Copy flag (falgs member), permission bit (pe_superpriv), and other flag.
    5. Call get_pid () to obtain a valid and unique PID for the sub-process.
    6. Copy the corresponding content based on the input cloning flags (specifically, the above. For example, open file symbols and signals.
    7. The Parent and Child processes divide the remaining time slices of the parent process equally.
    8. Return P; returns a pointer to the child process.

So far, the work of do_fork has basically ended.

 

 

 

 

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.