The fork function under Linux

Source: Internet
Author: User

之前只是了解到linux中的fork函数是用来创建进程,并没有太多的去学习,这里学习记录如下。

Writing is not easy, reprint need to indicate the source: http://blog.csdn.net/jscese/article/details/44401389 This article from the "Jscese" blog!

Defined:

Explanation from the Encyclopedia: thefork function divides the running program into 2 (almost) identical processes, each initiating a thread that executes from the same location in the code. The threads in both processes continue to execute, as if two users had started two copies of the application at the same time.

Popular to understand, that is, the program ran to fork, the time of a fen, and then two basic basic same fellow will be independent and then run down.

Prototype:
void);
return value:

Here the pid_t is a macro, defined by a series of types.h files, is actually an int type
One call to the fork function is two returns, one for the return of the calling process, and one for the new process.
The above mentioned when the call to fork, in the fork will be "fen", the replication of the resource state, so the creation of a new process is also stuck in the fork function, the call to the fork function process can be called the parent process, the new child process.

Fork return Value:
The parent process returns the process ID of the child process that was created.
The child process has just been created and has no child processes, so it returns 0 directly.
Returns a negative number if an error occurs.

There are two possible reasons for fork errors:
1) The current number of processes has reached the system-specified limit, when the value of errno is set to Eagain.
2) system memory is low, then the value of errno is set to Enomem.

Realize:

The fork function is defined in/usr/include/unistd.h and is actually called through the system.
Such a macro definition can be found in the unistd.h in the kernel source code:

#define __NR_fork 1079#ifdef CONFIG_MMU__SYSCALL(__NR_fork, sys_fork)#else__SYSCALL(__NR_fork, sys_ni_syscall)#endif /* CONFIG_MMU */

Continue to follow the implementation of Systemcall can see SYSCALLS.H and SYS_ARM.C, respectively, see the definition and implementation of Sys_fork:

/* Fork a new task - this creates a new program thread. * This is called indirectly via a small wrapper */int sys_fork(struct pt_regs *regs){#ifdef CONFIG_MMU    return0, NULL, NULL);#else    /* can not support in nommu mode */    return(-EINVAL);#endif}

You can see that a do_fork function is actually called. This is the interface that the fork is called into by the system.

Continue to look at this do_fork function, the implementation is in the kernel source under the/KERNEL/FORK.C (3.1.10):

/* Ok, this is the main fork-routine. * * It copies the process, and if successful kick-starts * it and waits for I T to finish using the VM if required. */LongDo_fork (unsigned LongClone_flags,unsigned LongStack_start,structPt_regs *regs,unsigned LongStack_size,int__user *parent_tidptr,int__user *child_tidptr) {structTask_struct *p;//And this task_struct struct is a descriptor for a process in Linux... p = copy_process (Clone_flags, Stack_start, Regs, Stack_size, Child_tidptr,NULL, trace);Copy- Copy the code snippet, data section, BSS segment, heap, stack and all the user space information}

The above is just a simple tracking of the implementation of the fork, especially the system calls and process resource replication are more complex, I do not touch much, here temporarily put down, follow-up have the opportunity to learn.

Use:

As a function of use, naturally inseparable from the code, the following attached to my own writing a small test:

#include <stdio.h>#include <unistd.h>intMainintargc,char* argv[]) {printf("begain parent process pid = =%x \ n", Getpid ());p id_t ipid1=Fork();if(ipid1==0){printf("first child process pid==%x , parent process pid==%x \ n", Getpid (), Getppid ());}Else{printf("First fork child process pid==%x , parent process pid==%x\ n", Ipid1,getpid ());} pid_t ipid2=Fork();if(ipid2==0){printf("second child process pid==%x , parent process pid = = %x \ n", Getpid (), Getppid ());}Else{printf("Second fork child process pid==%x , parent process pid==%x\ n", Ipid2,getpid ());}printf("========================================= \ n");Sleep(1);}

After the GCC compilation runs, the results are as follows:

Begain ParentProcessPID = = $FD First Fork ChildProcesspid== $Fe, ParentProcesspid== $Fdfirst ChildProcesspid== $Fe, ParentProcesspid== $FD Second Fork ChildProcesspid== $FF, parentProcesspid== $fd========================================= Second Fork ChildProcesspid==3700, the parentProcesspid== $fe========================================= second childProcesspid== $FF, parentProcessPID = = $FD ========================================= Second childProcesspid==3700, the parentProcessPID = = $Fe =========================================

You can see that the PID at the beginning of the main process is 36FD, after the first fork, it says that it will return two values, and will continue to execute the code snippet (two copies of the same code, not sharing data).

where the 36FD (parent) process returns the PID of the subprocess, so ipid1 is definitely not equal to 0, so run:

firstprocess pid==36process pid==36fd

It is clear that the returned child process PID is 36FE.
(Getpid () Gets the current process pid,getppid () Gets the parent process PID)

The 36FE sub-process created above must return 0, and execution ipid is equal to 0, so run:

firstprocess pid==36process pid==36

I am here the parent process runs out of fork first, so the first fork is printed, this should be related to the process scheduling policy, I am running directly on Ubuntu.

The code continues down, and the two processes (36FD (parent), 36FE (Child)) will enter the second fork function.
And then we will create a new process like the one above, which is 36ff 3670, which is analyzed in the same mode as above.

Finally, if you do not add a sleep (1);
The final two lines will be printed as follows:

process pid==36process1 =========================================  process pid==3700process1 =========================================  

Because when the latest two new processes run, the first two old processes run out ~getppid () returns 1

As for the total number of processes, you can see the ===== of the split line, because each process will run the last common code.

My preliminary understanding of the analysis is here ~ The following opportunity to go deep ....

The fork function under Linux

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.