-
clone()-fork()-exec()-exit()
子进程结束ZOMBIE
父进程wait4()
进程描述符task_struct
进程所有信息 由thread_info
分配。为了提高current
宏找进程描述符的速度,方便使用偏移量计算进程描述符 -
进程状态
TASK_RUNNING
TASK_INTERRUPTIBLE
TASK_UNINTERRUPTIBLE
TASK_ZOMBIE
TASK_STOP
-
用户空间——
sys_call
/异常——(进程上下文)内核空间 -
copy-on-write
写时拷贝其他以只读方式共享fork()
分配子进程页表和task_struck
.vfork()
不拷贝页表,其余同fork
,在无写时拷贝时代有利。如今相差无几
进程创建
Unix:fork()
和exec()
首先fork()
拷贝父进程,区别pid
和资源和统计量。fork()
实际开销是复制父进程的页表以及给子进程创建唯一的进程描述符。exec()
读取可执行文件载入地址空间运行。
clone() -> do_fork() -> copy_process():
-
dup_task_struck()
与父进程完全相同的内核栈thread_info
->task_struct
-
- 检查总进程数量小于
max
- 检查总进程数量小于
-
- 区分父子进程:
task_struct
成员清零或初始值
- 区分父子进程:
-
- 子进程
TASK_UNINTERRUPIBLE
不被执行
- 子进程
-
- 更新进程描述符的
flag
成员copy_flags() PF_SUPERPRIV=0
设置PF_FORKNOEXEC
(未执行标志)
- 更新进程描述符的
-
- 分配
alloc_pid()
- 分配
-
- 从
clone()
的输入参数中确定新进程行为方式和父子进程之间共享的资源种类eg: clone(CLONE_VM| CLONE_FS | CLONE_SIGHAND,0)
- 从
-
- 扫尾,返回
do_fork()
指向子进程的指针
- 扫尾,返回
-
copy_process–复制父进程的内核栈进程描述符等–检查进程数量–进程描述符设置初始值–设置UNINTERRUPTBLE–更新flags–分配pid–分配共享资源–返回指针给do_fork()
- 内核线程区别在于无独立地址空间
mm
指针->NULL
只在内核空间运行且由内核线程生成。 调用do_exit()
退出,或内核其他部分调用kthread_stop()
退出
进程终结
do_exit():
-
- 在进程描述符
task_struct
标志成员PF_EXITING
- 在进程描述符
-
del_time_sync()
删除内核定时器
-
- 若有
BSD
进程记账功能 输出信息
- 若有
-
exit_mm()
释放占用的mm_struct
若无其他进程使用此地址空间则彻底释放
-
sem_exit()
释放信号
-
exit_files(), exit_fs()
递减引用计数,若某引用计数为0释放资源
-
exit_code()
设为exit()
-