您的位置:首页 > 运维架构 > Linux

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

2018-01-30 19:46 525 查看
[align=center]Linux中fork系统i调用的源码剖析[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]首先 先给大家看一张图 系统的看一下大概的fork的主要流程[/align]
[align=left]
[/align]



[align=left]上述图片中 最后eax寄存器置0 这个就是最后为什么子进程的返回值是0的理由[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]下面 就来浅谈一下 fork源码[/align]



[align=left]long do_fork(unsigned long clone_flags,[/align]

      unsigned long stack_start,
      struct pt_regs *regs,
      unsigned long stack_size,
      int __user *parent_tidptr,
      int __user *child_tidptr)
先说这几个参数:<
4000
/span>
(1)clone_flags:应该是标志位有选择的复制父进程
(2)stack_start:堆栈的起始地址
(3)regs:结构体指针上面说的是指向通用寄存器的值。是在从用户态切换到内核态时被保存到内核态堆栈中的
(4)stack_size:堆栈的大小
(5)parent_tidptr:存放父进程pid的指针(地址)
(6)child_tidptr:存放父进程pid的指针(地址)

 

具体的实现步骤:

 

1、

 


 

定义了一个结构体指针  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是否执行成功


 

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、


 

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)):如果子进程的
c9bf
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、


 

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

最后返回pid

 

 

 

[align=left][/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: