do_fork

原创 2011年01月09日 15:31:00

1. 分配pid

long pid = alloc_pidmap();

 

2. 检查ptrace

    if (unlikely(current->ptrace)) { /*父进程被跟踪*/
        trace = fork_traceflag (clone_flags);
        if (trace)    /* 如果不是内核线程(no UNTRACED flag) */
            clone_flags |= CLONE_PTRACE;
    }

 

3. 调用copy_process() 复制进程描述符

 

4. 检查vfork flag. 如果是初始化vfork wait flag

        if (clone_flags & CLONE_VFORK) {
            p->vfork_done = &vfork;
            init_completion(&vfork);
        }

 

5. 检查是否pending

        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);
        }

 

6. 检查stopped标志

1). 如果没有设置stopped标志

        if (!(clone_flags & CLONE_STOPPED))
            wake_up_new_task(p, clone_flags);

 

2). stopped被设置
            p->state = TASK_STOPPED;

 

7. wake_up_new_task()

1). 如果未设VM, 插子进程在父进程运行队列,恰好在父进程前面

        if (!(clone_flags & CLONE_VM)) {
            /*
             * The VM isn't cloned, so we're in a good position to
             * do child-runs-first in anticipation of an exec. This
             * usually avoids a lot of COW overhead.
             */
            if (unlikely(!current->array))
                __activate_task(p, rq);
            else {
                p->prio = current->prio;
                list_add_tail(&p->run_list, &current->run_list); //前面
                p->array = current->array;
                p->array->nr_active++;
                rq->nr_running++;
            }
            set_need_resched();
        }


2). 否则不是同一cpu或者VM被设置,子进程插入父进程运行队列的队尾

__activate_task(p, rq);

 

8. 检查跟踪标志

        if (unlikely (trace)) {
            current->ptrace_message = pid; /* pid存入message */

            ptrace_notify ((trace << 8) | SIGTRAP); /*SIGCHLD, 通知子进程的祖父进程(当前进程的父进程debugger), current创建了子进程,可以通过查找current->ptrace_message字段获得子进程的PID*/
        }

 

9. 如果设置VFORK, 把父插入等待队列,直到子进程释放自己的内存地址空间

 

10. 结束返回子进程的pid

Linux的do_fork函数的执行过程

linux的do_fork函数的执行过程。

do_fork->copy_process->copy_mm

static int copy_mm(unsigned long clone_flags, struct task_struct * tsk) { struct mm_struct * mm, *o...

do_fork()浅析

linux-2.6.36.3 /*  *  Ok, this is the main fork-routine.  *  * It copies the process, and if suc...

《深入理解Linux内核》do_fork函数

看到进程clone、fork 和 vfork这章时,些许问题不明白,遂百度,粘贴下他人成果如下。一来作积累之用,二来亦可方便他人搜索。   《clone fork及vfork的区别》   摘自 ...

linux do_fork()源代码分析

//网上有很多分析do_fork(),但是将的都不详细。这个会比较详细。 do_fork()分析 从上文可得知, fork、vfork和clone三个系统调用所对应的系统调用服务例程均调用...

Linux内核进程管理-do_fork()执行过程分析

/* * SMP负载均衡:http://linux.chinaitlab.com/kernel/888181.html * 命名空间:http://prettyinsight.iteye.co...
  • s_a_n_
  • s_a_n_
  • 2013年09月15日 22:00
  • 839

我看task_struct结构体和do_fork函数

先来看看task_struct结构体。 众所周知,task_struct结构体是用来描述进程的结构体,进程需要记录的信息都在其中,下面我们来看看其中的具体项目。结构体存储在linux/sched.h...
  • sium__
  • sium__
  • 2015年10月15日 17:32
  • 651

do_fork情景分析

内核的版本是3.10.9. 我自己的分析使用棕色字 long do_fork(unsigned long clone_flags,           unsigned long stack_sta...

Linux进程创建二——do_fork

前言 kernel在启动初期并没有“进程”这个概念,如果不涉及支持多任务并发、调度,kernel可以一直以一个控制流运行。本篇从内核初始化时的0进程开始分析,延伸到多进程的创建。 0 进程 内核...
  • yin262
  • yin262
  • 2017年01月17日 21:12
  • 276

内核 do_fork 函数源代码浅析

http://linux.chinaunix.net/bbs/thread-1051510-1-1.html 前面已经谈了内核加载与系统引导过程,下面我们来看看内核的 do_fork() 函数是...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:do_fork
举报原因:
原因补充:

(最多只允许输入30个字)