Linux中fork系统调用的源码剖析

Linux中fork系统i调用的源码剖析


首先 先给大家看一张图 系统的看一下大概的fork的主要流程

Linux中fork系统调用的源码剖析_第1张图片
上述图片中 最后eax寄存器置0 这个就是最后为什么子进程的返回值是0的理由



下面 就来浅谈一下 fork源码
Linux中fork系统调用的源码剖析_第2张图片
long do_fork(unsigned long clone_flags,

      unsigned long stack_start,

      struct pt_regs *regs,

      unsigned long stack_size,

      int __user *parent_tidptr,

      int __user *child_tidptr)

先说这几个参数:

(1)clone_flags应该是标志位有选择的复制父进程

(2)stack_start堆栈的起始地址

(3)regs结构体指针上面说的是指向通用寄存器的值。是在从用户态切换到内核态时被保存到内核态堆栈中的

(4)stack_size堆栈的大小

(5)parent_tidptr存放父进程pid的指针(地址)

(6)child_tidptr存放父进程pid的指针(地址)

 

具体的实现步骤:

 

1

 

Linux中fork系统调用的源码剖析_第3张图片 

定义了一个结构体指针  struct task_struct *p  应该是接受子进程的pid

long pid = alloc_pidmap();这应该是给子进程分配pid

If(pid < 0)

return -EAGAIN;  这应该是判断子进程的pid是否分配成功

 

 

2、检查进程是否被跟踪

 

如果父进程被跟踪就要判断子进程是否被跟踪

如果子进程不是内核进程就设置CLONE_PTRACE标志

 

3、通过copy_process复制进程描述符

 

 

4、判断通过copy_process是否执行成功

Linux中fork系统调用的源码剖析_第4张图片 

if (!IS_ERR(p)):如果不是错误的 意思就是如果成功

struct completion vfork;定义一个结构体变量vfork completion有完成的意思 那就是定义了一个完成量vfork

if (clone_flags & CLONE_VFORK):如果clone_flags标志位有CLONE_VFORK

p->vfork_done = &vfork;让进程描述符p->vfork_done指向vfork

init_completion(&vfork);初始化这个vfork

 

5、

Linux中fork系统调用的源码剖析_第5张图片 

if ((p->ptrace & PT_PTRACED) || (clone_flags & CLONE_STOPPED))如果子进程被跟踪或者 clone_flags标志位有CLONE_STOPPED 

sigaddset(&p->pending.signal, SIGSTOP);通过sigaddset函数给子进程发送SIGSTOP信号

set_tsk_thread_flag(p, TIF_SIGPENDING);这个不懂

 

6

 

if (!(clone_flags & CLONE_STOPPED)):如果子进程的clone_flags标志位没有CLONE_STOPPED这个标志

wake_up_new_task(p, clone_flags);调用wake_up_new_task函数

else

p->state = TASK_STOPPED;如果CLONE_STOPPED标志被设置,就把子进程设置为TASK_STOPPED状态

 

7、如果父进程被跟踪,则将子进程的pid赋值给父进程的pstrace_message字段。

 

调用ptrace_notify()这个函数可以使当前进程停止 并向当前进程的父进程发送SIGCHLD信号

 

8

 

if (clone_flags & CLONE_VFORK):如果clone_flags标志位有CLONE_VFORK标志

wait_for_completion(&vfork);调用wait_for_completion()函数 这个函数是干嘛的

if (unlikely (current->ptrace & PT_TRACE_VFORK_DONE))

ptrace_notify ((PTRACE_EVENT_VFORK_DONE << 8) | SIGTRAP);

 

9

Linux中fork系统调用的源码剖析_第6张图片 

如果copy_process()在执行的时候发生错误了 就先释放已分配的pid再让PTR_ERR()的返回值得到错误码赋值给pid

最后返回pid

 

 


 















































































你可能感兴趣的:(Linux)