关闭

do_fork

标签: listthreadup
1274人阅读 评论(0) 收藏 举报

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

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:903858次
    • 积分:10524
    • 等级:
    • 排名:第1567名
    • 原创:138篇
    • 转载:483篇
    • 译文:0篇
    • 评论:43条
    文章分类
    最新评论
    Linux 参考手册