Read the core diary fork

xiaoxiao2021-03-06  42

Author: handi Thursday, October 28, 2004

Read the core diary fork

In the middle of the information and article, I will also list this one by one by the diary 1. Lion's UNIX source code analysis 2. Kernel 2.6.8 /kernel/fork.c3. Kernel 2.4.18 /kernel/fork.c4. Linux scenario analysis (upper, bottom)

Basically, no functions named by fork, but also comply with Match Case and Match Whold Word ONLY

So Sys_Fork -> do_fork, just like SOCKET, only sys_socket is forfell () and socket () when the system is called, I think it may be the reason for the function Map.

Let's talk about the general process, then explain the code first, check some states, get some necessary information -> Enter the COPY_PROCESS entity, copy the process (there is a very important point in the middle, is why the child process returns 0) -> Set some information -> Let the process start Run

Compared to UNIX, I can only say that Linux is really complicated and Luo Wei. The implementation in Lion's Unix is ​​very simple and clear. If you just want to understand the principle, the FORK is enough, and very honest, no sys_fork, v_fork, DO_FORK, nested, just a fork

Of course, I don't know how this is implemented in UNIX version, so I will find some code implemented in Minix or BSD for reference, and then add to the diary.

The front is so much, or let's analyze the source code ./kernel/fork.c

KERNEL_THREAD (), SYS_FORK (), SYS_CLONE (), SYS_VFORK () These various functions are calling the do_fork () function, the main parameters are concentrated on Clone_Flags, on /arch/i386/kernel/process.c

/ * * Ok, this is the main fork-routine. * * It copies the process, and if successful kick-starts * it and waits for it to finish using the VM if required. * / Long do_fork (unsigned long clone_flags, / * Clone logo * / unsigned long stack_start, / * Stack starting position - how do you not need a pointer? * / Struct pt_regs * regs, / * register * / unsigned long stack_size, / * stack size * / int __user * Parent_tidptr, / * Father What pointer to the process * / int __User * child_tidptr) / * What pointer does the child process? * / {Struct task_struct * p; / * PCB structure * / int track = 0; long pid;

/ * Clone_ptrace This macro said in what is the meaning on the child to let tracing continue on the child TOO] * Translated means that if you want to track the sub-process, set this bit * whether tracking by Do_Fork's parameter clone_flags determined * That means that the information of the tracking sub-process is determined by us when calling * /

/ * CURRENT This refers to the current parent process? * Unlikely prototype: * #include * / if (unlikely (current-> ptrace)) {/ * unlikely (x), two times Inverse, specific implementation depends on the GCC version, GCC 2.9.6 is the boundary, in fact, the value of X * / trace = fork_traceflag (clone_flags); / * fork_traceflag inline In Fork.c, version 2.4.18 is not Outline * / if (trace) clone_flags | = clone_ptrace;} / * Check Clone_Flags, create a new process, copy the information specified by clone_flags, but the new process does not run * /

P = copy_process (clone_flags, stack_start, regs, stack_size, parent_tidptr, child_tiDPTR);

/ * * Do this prior WAKING UP THE New Thread - The Thread Pointer * Might Get Invalid After That Point, IF The Thread EXITS Quickly. * / PID = IS_ERR (P)? PTR_ERR (P): P-> PID;

/ * Process replication success * / if (! Is_err (p)) {struct completion vfork;

IF (clone_flags & clone_vfork) {p-> vFork_done = & vfork; init_completion (& vfork);}

if ((p-> ptrace & PT_PTRACED) || (clone_flags & CLONE_STOPPED)) {/ * * We'll start up with an immediate SIGSTOP * / sigaddset (& p-> pending.signal, SIGSTOP);. set_tsk_thread_flag (p, TiF_sigpending);

if (! (clone_flags & CLONE_STOPPED)) {/ * * Do the wakeup last. On SMP we treat fork () and * CLONE_VM separately, because fork () has already * created cache footprint on this CPU (due to * copying the pagetables .), hence migration would * probably be costy Threads on the other hand * have less traction to the current CPU, and if * there's an imbalance then the scheduler can * migrate this fresh thread now, before it * accumulates a larger cache footprint: * / / * new fork wakeup process * / if (clone_flags & CLONE_VM) wake_up_forked_thread (p); else wake_up_forked_process (p);} else {int cpu = get_cpu (); p-> state = TASK_STOPPED; if (cpu_is_offline (task_cpu (p)))) SET_TASK_CPU (P, CPU);

PUT_CPU (); Total_Forks;

IF (unlikely (trarent) {current-> ptrace_message = pid; ptrace_notify ((Trace << 8) | SigTrap);}

if (clone_flags & CLONE_VFORK) {wait_for_completion (& vfork); if (unlikely (current-> ptrace & PT_TRACE_VFORK_DONE)) ptrace_notify ((PTRACE_EVENT_VFORK_DONE << 8) | SIGTRAP);} else / * * Let the child process run first, to avoid MOST OF THE * COW OVERHEAD WHEN THE CHILD EXEC () s afterwards. * / / * Let the child process run * / set_need_resched ();} return pid;}

转载请注明原文地址:https://www.9cbs.com/read-67939.html

New Post(0)