zoukankan      html  css  js  c++  java
  • [转]进程创建-终结流程图

    From: http://blog.csdn.net/xinyuan510214/article/details/50516279

    arch/x86/include/asm/unistd_32.h:fork()        用户空间来调用(如C程序)
    	--->int $0×80		产生0x80软中断
    	--->arch/x86/kernel/entry_32.S:ENTRY(system_call)  中断处理程序system_call()
    		--->执行SAVE_ALL宏		保存所有CPU寄存器值
    		--->arch/x86/kernel/syscall_table_32.S:ENTRY(sys_call_table) 系统调用多路分解表
    	--->arch/x86/kernel/process_32.c:sys_fork()
    		--->kernel/fork.c:do_fork()  复制原来的进程成为另一个新的进程
    			--->kernel/fork.c:copy_process()
    				--->struct task_struct *p;  定义新的进程描述符(PCB)
    				--->clone_flags标志的合法性检查
    				--->security_task_create()    安全性检查(SELinux机制)
    				--->kernel/fork.c:dup_task_struct()   复制进程描述符
    					--->struct thread_info *ti;  定义线程信息结构
    					--->alloc_task_struct()      为新的PCB分配内存
    					--->kernel/fork.c:arch_dup_task_struct()  复制父进程的PCB
    					--->atomic_set(&tsk->usage,2)    将PCB使用计数器设置为2,表示活动状态
    				--->copy_creds()   复制权限及身份信息
    				--->检测进程总数是否超过max_threads
    				--->初始化PCB中各个字段
    				--->sched_fork()    调度器相关设置
    				--->复制进程所有信息copy_semundo(), copy_files(),
    				--->copy_signal(), copy_mm()
    				--->copy_thread()    复制线程
    				--->alloc_pid()    分配pid
    				--->更新属性和进程数量计数
    			--->kernel/sched.c:wake_up_new_task()  把进程放到运行队列上,让调度器进行调度
    				--->kernel/sched.c:select_task_rq()  选择最佳的CPU(SMP中有多个CPU)
    				--->p->state = TASK_RUNNING    设置成TASK_RUNNING状态
    				--->activate_task()
    					--->enqueue_task()  把当前进程插入到对应CPU的runqueue上
    			--->有CLONE_VFORK标志:wait_for_completion()  让父进程阻塞,等待子进程结束
    			--->返回分配的pid
    kernel/sched.c:schedule()    调度新创建的进程
    进程运行中
    exit()        用户空间来调用(如C程序)
    	--->0x80中断跳转到include/linux/syscalls.h:sys_exit()
    		--->kernel/exit.c:do_exit()    负责进程的退出
    			--->struct task_struct *tsk = current;    获取我的PCB
    			--->set_fs(USER_DS)    设置使用的文件系统模式
    			--->exit_signals()     清除信号处理函数并设置PF_EXITING标志
    			--->清除进程一系列资源exit_mm(), exit_files() 
    			--->exit_fs(), exit_thread()
    			--->kernel/exit.c:exit_notify()  退出通知
    				--->forget_original_parent()  把我的所有子进程过继给init进程
    				--->kill_orphaned_pgrp()      向进程组内各进程发送挂起信号SIGHUP及SIGCONT
    				--->tsk->exit_signal = SIGCHLD;  向我的父进程发送SIGCHLD信号
    				--->kernel/exit.c:do_notify_parent()  通知父进程
    					--->如果父进程处理SIGCHLD信号,返回DEATH_REAP
    					--->如果父进程不处理SIGCHLD信号,返回传入时的信号值
    					--->__wake_up_parent()    唤醒父进程
    				--->通知返回DEATH_REAP,设置exit_state为EXIT_DEAD    我退出并且死亡
    				--->否则设置我为EXIT_ZOMBIE      我退出但没死亡,成为僵尸进程
    				--->如果为DEATH_REAP:release_task()    我自己清理相关资源
    				--->如果为僵尸,在我的父进程退出时我会过继给init进程,由init负责清理
    			--->exit_io_context()    清理IO上下文
    			--->preempt_disable()    禁用抢占
    			--->tsk->state = TASK_DEAD;    设置我为进程死亡状态
    			--->kernel/sched.c:schedule()  释放我的PCB,调度另一个新的进程
    
    清理僵尸进程:wait系统调用			等待子进程结束
    	--->0x80中断最后到达kernel/exit.c:do_wait()
    		--->do_wait_thread()
    			--->wait_consider_task()
    				--->如果子进程为EXIT_DEAD,返回0,wait调用返回,子进程自己清理自己
    				--->如果子进程为EXIT_ZOMBIE:wait_task_zombie()
    					--->xchg()    设置僵尸子进程为EXIT_DEAD
    					--->release_task()    清理僵尸子进程
    

      

  • 相关阅读:
    BZOJ 2034 【2009国家集训队】 最大收益
    vijos P1780 【NOIP2012】 开车旅行
    BZOJ 2115 【WC2011】 Xor
    BZOJ 3631 【JLOI2014】 松鼠的新家
    BZOJ 4717 改装
    BZOJ 2957 楼房重建
    BZOJ 4034 【HAOI2015】 T2
    BZOJ 1834 【ZJOI2010】 network 网络扩容
    BZOJ 2440 【中山市选2011】 完全平方数
    BZOJ 2733 【HNOI2012】 永无乡
  • 原文地址:https://www.cnblogs.com/hushpa/p/5689098.html
Copyright © 2011-2022 走看看