进程调度之创建进程

do_fork
	=>struct pid *pid = alloc_pid();
		=>struct pid *pid = kmem_cache_alloc(pid_cachep, GFP_KERNEL);//分配pid结构体空间
		=>nr = alloc_pidmap(current->nsproxy->pid_ns);//分配PID进程号
		=>pid->nr = nr;//关联
		=>for (type = 0; type < PIDTYPE_MAX; ++type)//初始化进程PID, PGID和SID私有hash表
			==>INIT_HLIST_HEAD(&pid->tasks[type]);
		=>hlist_add_head_rcu(&pid->pid_chain, &pid_hash[pid_hashfn(pid->nr)]);//将进程pid加入进程全局hash表
		=>return pid;//返回pid结构体
	=>p = copy_process(clone_flags, stack_start, regs, stack_size, parent_tidptr, child_tidptr, pid);//拷贝父进程的东东到子进程
                =>p = dup_task_struct(current);
                    =>struct task_struct *tsk = alloc_task_struct();
            	    =>struct thread_info *ti = alloc_thread_info(tsk);
            	    =>*tsk = *orig;//建立task_struct和thread_info的关系
            	    tsk->stack = ti;
            	    setup_thread_stack(tsk, orig);
            	=>retval = copy_files(clone_flags, p)//拷贝父进程的资源
            	retval = copy_fs(clone_flags, p)
            	retval = copy_sighand(clone_flags, p)
            	retval = copy_mm(clone_flags, p)
            	=>if (clone_flags & (CLONE_PARENT|CLONE_THREAD))//建立父子关系和伙伴关系列表
                	p->real_parent = current->real_parent;
            	else
                	p->real_parent = current;
            	p->parent = p->real_parent;
            	=>if (clone_flags & CLONE_THREAD)//如果是线程,则认祖归宗,找到组织
                    =>p->group_leader = current->group_leader;
                    =>list_add_tail_rcu(&p->thread_group, &p->group_leader->thread_group);//插入到领头线程的链表;新版本取消掉了TGID哈希表
            	=>if (likely(p->pid))
                	==>add_parent(p);
               	 		==>if (thread_group_leader(p)) 
                    			p->signal->tty = current->signal->tty;
                    			p->signal->pgrp = process_group(current);
                    			set_signal_session(p->signal, process_session(current));
                    			attach_pid(p, PIDTYPE_PGID, task_pgrp(current));//将P加入到当前进程的各种哈希链表中
                        			=>struct pid_link *link;
                                     link = &task->pids[type];
                                     link->pid = pid;//指向领头进程的Pid
                                     hlist_add_head_rcu(&link->node, &pid->tasks[type]);//加到领头进程的哈希表
                    			attach_pid(p, PIDTYPE_SID, task_session(current));
                    			list_add_tail_rcu(&p->tasks, &init_task.tasks);
                		==>attach_pid(p, PIDTYPE_PID, pid);
                =>retval = copy_thread_tls(clone_flags, stack_start, stack_size, p, tls);
                    frame->ret_addr = (unsigned long) ret_from_fork; // 新进程的第一条指令
    =>wake_up_new_task(p, clone_flags);//将新进程加到就绪队列,专门一章用来讲这个
    =>return nr;//返回进行PID给应用层,PID结构体对应用层不可见

如果创建子进程,那么还有如下场景需要处理

if (clone_flags & CLONE_VFORK)//CLONE_VFORK代表创建子进程
	wait_for_completion(&vfork);//等一下子进程

 

加载子进程会通过execve系统调用进行

 

.load_binary	= load_aout_binary
	=>retval = flush_old_exec(bprm);
		=>retval = exec_mmap(bprm->mm);
			=>mm_release(tsk, old_mm);
				=>if (vfork_done) {
					if (vfork_done) {
					complete(vfork_done);//通知父进程可以继续进行
				}

 

 

进程名在内核态如何获取,方法是 current->comm,作为字符串打印即可

 

 

参考文章:

进程创建之copy_process函数
https://blog.csdn.net/bullbat/article/details/7088484
 

[进程管理] copy_thread函数的一些不理解的地方,求助大家?  好文
http://bbs.chinaunix.net/thread-4180012-1-1.html

linux内核分析之fork()
https://www.cnblogs.com/qiuheng/p/5752284.html

Linux进程描述符task_struct结构体详解--Linux进程的管理与调度(一)
https://blog.csdn.net/gatieme/article/details/51383272

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值