do_fork

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值