[轉]進程建立-終結流程圖

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

 

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()    清理殭屍子進程

  

相關文章
相關標籤/搜索