[转]进程创建-终结流程图

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()    清理僵尸子进程

  

时间: 2024-10-10 10:28:34

[转]进程创建-终结流程图的相关文章

理解Android进程创建流程(转)

/frameworks/base/core/java/com/android/internal/os/ - ZygoteInit.java - ZygoteConnection.java - RuntimeInit.java - Zygote.java /frameworks/base/core/java/android/os/Process.java /frameworks/base/core/jni/com_android_internal_os_Zygote.cpp /frameworks

Linux进程创建、可执行文件的加载和进程执行进程切换

作者:刘磊 文中参考代码出处:https://github.com/mengning/linuxkernel/ 本文主要针对进程创建.可执行文件的加载和进程间切换三大部分进行实验并分析. 实验环境:Ubuntu 16虚拟机.VMware 14 1 进程创建 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础.在早期面向进程设计的计算机结构中,进程是程序的基本执行实体:在当代面向线程设计的计算机结构中,进程是线程的容器.程

进程创建

这篇是网易云课堂<Linux内核分析>这门课的作业 Linux提供了三个系统调用创建进程,v_fork, fork和clone.fork是将父进程的所有资源都复制给了子进程,所以不带参数.而clone是将指定资源复制给子进程,所以带参数.不论哪种方式最终都要调用do_fork. long do_fork(unsigned long clone_flags, unsigned long stack_start, unsigned long stack_size, int __user *pare

Linux-进程描述(4)之进程优先级与进程创建执行

进程优先级 进程cpu资源分配就是指进程的优先权(priority).优先权高的进程有优先执行权利. 权限与优先级.权限(privilege)是指在多用户计算机系统的管理中,某个特定的用户具有特定的系统资源使用权力,像是文件夹,特定系统指令的使用或存储量的限制.权限是有或没有的问题,而优先级则是在已经具有了权限而讨论权限大小的问题.配置进程优先权对多任务环境的linux很有用,可以改善系统性能.还可以把进程运行到指定的CPU上,这样一来,把不重要的进程安排到某个CPU,可以大大改善系统整体性能.

ring3下利用WMI监视进程创建(vc版)

[cpp] view plain copy #include "stdafx.h" #define _WIN32_DCOM #include <iostream> using namespace std; #include <comdef.h> #include <Wbemidl.h> # pragma comment(lib, "wbemuuid.lib") int main(int argc, char **argv) { H

Windows内核原理研究——进程创建

进程可能是用户接触的Windows系统中最多的部分了,对于Windows系统而言,进程是一个独立的地址空间可以为线程提供一个独立的执行环境, 也就是说 进程= 独立的地址空间 一个进程内核对象 线程= 一个线程自己的栈 一个线程内核对象 当然这个栈是在进程的地址空间中.那么,也就是说线程才是真正“干活”的东西,进程只不过是一些资源的集合而已.只能说是“原材料”. 在我学习Windows内核以前一直觉得进程的种种特性很神奇,比如说地址空间独立是怎么实现的呢?我们的电脑使用的都是同一块内存怎么能实现

Linux进程创建和结束

在Linux中,进程的创建由系统调用fork和vfork完成.它们生成一个子进程并且子进程是父进程的一个复制品. Fork系统调用对应的kernel函数是sys_fork,此函数简单的调用kernel函数do_fork.一个简化版的do_fork执行如下: (1)alloc_pid().给新的进程分配一个新的pid,即进程号 (2)copy_process()此函数会做fork的大部分事情,它主要完成讲父进程的运行环境复制到新的子进程,比如信号处理.文件描述符和进程的代码数据等. (3)wake

进程创建与销毁

Unix操作系统紧紧依赖进程创建来满足用户需求 创建进程 Unix创建进程的三种机制 1.写时复制技术运行父子进程读相同的物理页.只要两者中有一个试图写一个物理页,内核就把这个页的内容拷贝到    一个新的物理页,并把这个新的物理页分配给正在写的进程. 2.轻量级进程允许父子进程共享每个进程在内核的很多数据结构,如页表(整个用户态的地址空间).打开文件表及信    号处理. 3.vfork()系统调用创建的进程能共享其父进程的内存地址空间.为了防止父进程重写子进程需要的数据,阻塞父进    程的

python的multiprocessing模块进程创建、资源回收-Process,Pool

python的multiprocessing有两种创建进程的方式,每种创建方式和进程资源的回收都不太相同,下面分别针对Process,Pool及系统自带的fork三种进程分析. 1.方式一:fork() 举例: 1 import os 2 pid = os.fork() # 创建一个子进程 3 os.wait() # 等待子进程结束释放资源 4 pid为0的代表子进程. 缺点:1.兼容性差,只能在类linux系统下使用,windows系统不可使用:2.扩展性差,当需要多条进程的时候,进程管理变得