20135320赵瀚青LINUX第三章读书笔记
第三章 进程管理
3.1 进程
进程的定义:
是处于执行期的程序以及它所包含的资源的总称。
线程的定义:
是在进程中活动的对象。
每个线程都拥有一个独立的程序计数器、进程栈和一组进程寄存器。
内核调度的对象是线程,而不是进程。
3.2 进程描述符及任务结构
进程描述符的结构:task_struct,定义在<linux/sched.h>中,包含一个具体进程的所有信息。
task_struct 就是指 PCB (进程控制块)。
3.2.1 分配进程描述符
thread_info结构在文件<asm/thread_info.h>中。
3.2.2 进程描述符的存放
3.2.3 进程状态
1.TASK_RUNNING (运行):无论进程是否正在占用 CPU ,只要具备运行条件,都处于该状态。 事实上, Linux 是将就绪态和运行态合并为了一种状态。
2.TASK_INTERRUPTIBLE (可中断阻塞):在资源有效时被唤醒,也可以通过信号或定时中断唤醒。
3.TASK_UNINTERRUPTIBLE (不可中断阻塞):另一种阻塞状态,处于该状态的进程只有当资源有效时被唤醒,不能通过信号或定时中断唤醒。
4.TASK_STOPPED (暂停):第三种阻塞状态,进程被停止,通常是通过接收一个信号SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU。
5.TASK_ZOMBILE (僵死):进程已结束但尚未消亡,已经释放了大部分资源, PCB 仍未被释放,在task数据中仍然保留task_struct结构。一旦父进程调用了wait4(),进程描述符就会被释放。
3.2.4 设置当前进程状态
set_task_state(task, state); /* 设置任务 'task' 的状态变成 'state' */
3.2.5 进程上下文
内核“代表进程执行”并处于进程上下文中。
此上下文中current宏有效。
3.2.6 进程家族树
1.获得父进程的进程描述符:
struct task_struct *my_parent = current->parent;
2.依次访问子进程:
struct task_struct *task;
struct list_head *list;
list_for_each(list, ¤t->children) {
task = list_entry(list, struct task_struct, sibling);
/* task指向当前某个子进程*/
}
3.获取链表中的下一个进程:
list_entry(task->tasks.next, struct task_struct, tasks)
4.获取链表中的前一个进程:
list_entry(task->tasks.prev, struct task_struct, tasks)
5.宏for_each_process(task),提供了依次访问整个任务队列的能力,
struct task_struct *task;
for_each_process(task) {
/* 打印出每个任务名称和pid*/
printk("%s[%d]\n", task->comm, task->pid);
}
3.3 进程创建
3.3.1 写时拷贝
fork() 和 exec()
fork():通过拷贝当前进程创建一个子进程。
exec():负责读取可执行文件并将其载入地址空间开始运行。
3.3.2 fork()
通过clone()系统调用实现fork()。
do_fork完成创建中大量工作,定义在kernel/fork.c文件中。
调用copy_process()函数让进程开始运行。(具体工作很有意思详见《Linux内核设计与实现》第27页)
3.3.3 vfork()
与fork()很类似。
实现是通过向clone()系统调用传递一个特殊标志来进行。(具体工作很有意思详见《Linux内核设计与实现》第28页)
3.4 线程在Linux中的实现
3.4.1 创建线程
在调用clone()需传递一些参数标志指明共享资源。
clone(CLONE_VM | CLONE_FS | CLONE_SIGHAND, 0);
新建的进程和他的父进程就是线程。
一个普通的fork()。
clone(SIGHAND, 0);
vfork()的实现。
clone(CLONE_VFORK | CLONE_VM | SIGHAND, 0);
clone()参数标志决定新创建进程的行为方式和父子进程之间共享的资源种类。(具体参数标识详见《Linux内核设计与实现》第29-30页)
3.4.2 内核线程
内核线程只能由其他内核线程创建。
内核通过从kthreadd内核进程中衍生出所有新内核线程来自动处理。
在<linux/kthread.h>中声明接口。
新的任务是由kthread内核进系统调用程通过clone()而创建的。
内核线程启动后一直运行知道调用do_exit()退出,或者内核其它部分调用kthread_stop()退出。
3.5 进程终结
进程的退出一般是显示或隐式地调用了exit(),或者接受了某种信号。
只要退出,最终都调用了do_exit()(具体完成的繁琐工作详见《Linux内核设计与实现》第31页)。
3.5.1 删除进程描述符
wait()会暂时停止目前进程的执行,直到有信号来到或子进程结束。如果执行成功则返回子进程识别码(PID),如果有错误发生则返回-1。
最终需要释放进程描述符时,release_task()会被调用(具体需要完成的工作详见《Linux内核设计与实现》第32页)
3.5.2 孤儿进程造成的进退维谷
如果父进程在子进程之前退出,必须有机制来保证子进程能找到一个新的父亲,否则这些成为孤儿的进程就会在退出时永远处于僵死状态。
解决方法是给子进程在当前线程组内找一个线程作为父亲,如果不行,就让init做它们的父进程。在do_exit()中会调用exit_notify(),该函数会调用forget_original_parent(),而后者会调用find_new_reaper()来执行寻父。
遍历了两个链表:子进程链表和ptrace子进程链表,给每个子进程设置新的父进程。
20135320赵瀚青LINUX第三章读书笔记的更多相关文章
- 20135320赵瀚青LINUX第五章读书笔记
第五章--系统调用 5.1 与内核通信 作用 1.为用户空间提供一种硬件的抽象接口 2.保证系统稳定和安全 3.除异常和陷入,是内核唯一的合法入口. API.POSIX和C库 关于Unix接口设计:提 ...
- 20135320赵瀚青LINUX第四章读书笔记
概述 什么是进程调度 进程调度:在可运行态进程之间分配有限处理器时间资源的内核子系统. 一.调度策略 4.1进程类型 I/O消耗型进程:大部分时间用来提交I/O请求或是等待I/O请求,经常处于可运行状 ...
- 20135320赵瀚青LINUX第十八章读书笔记
概述:调试工作艰难是内核级开发区别于用户级开发的一个显著特点 18.1准备开始 内核调试往往是一个令人挠头不已的漫长过程.幸运的是,在这些费劲的问题中也有不少比较简单而且容易消灭的小bug,运气好你可 ...
- 20135320赵瀚青LINUX第五周学习笔记
赵瀚青原创作品转载请注明出处<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 概述 按照刘老师的周从三个角 ...
- 20135320赵瀚青LINUX第六周学习笔记
赵瀚青原创作品转载请注明出处<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 概述 这周主要讲解的是进程. ...
- 20135320赵瀚青LINUX第八周学习笔记
赵瀚青原创作品转载请注明出处<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 概述 本周学习的是linux ...
- 20135320赵瀚青LINUX第七周学习笔记
赵瀚青原创作品转载请注明出处<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 概述 本周学习的内容主要是讨 ...
- 三20135320赵瀚青LINUX内核分析第二周学习笔记
赵瀚青原创作品转载请注明出处<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.计算机的三个法宝 存储程 ...
- 20135320赵瀚青LINUX内核分析第三周学习笔记
赵瀚青原创作品转载请注明出处<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 概述 本周是学习的主要是构造 ...
随机推荐
- Hibernate的检索方式--查询数据的方式
Hibernate 提供了以下几种检索对象的方式1导航对象图检索方式: 根据已经加载的对象导航到其他对象(根据已经加载的对象,导航到其他对象-例如一对多的查询)2OID 检索方式: 按照对象的 OID ...
- 配置Hibernate的流程
配置项目的前提下你应该配置好你的开发环境 1新建hibernate.cfg.xml文件,放在src目录里 <?xml version="1.0" encoding=" ...
- Oracle涂抹oracle学习笔记第10章Data Guard说,我就是备份
DG 是备份恢复工具,但是更加严格的意义它是灾难恢复 Data Guard是一个集合,由一个Primary数据库及一个或者多个Standby数据库组成,分两类逻辑Standby和物理Standby 1 ...
- HTML5跨平台开发环境配置
http://hi.baidu.com/kuntakinte/item/1bbd3759b4901a3695eb050c
- c# 日常记录,(获取系统时间、return),一些文件隐藏无法引用,c#多个窗体之间传值
1.获取系统时间 DateTime.Now.ToString(); DateTime dt =DateTime.Now; dt.AddDays(1); //增加一天 dt.AddDays(-1);// ...
- Exchange Management Console Error
Exchange 2010 error solved : The WS-Management service cannot process the request. The system load q ...
- 微软构建高效DevOps团队培训总结
9.21和9.22这两天参加了微软DevOps的培训,主要是围绕TFS2015的不少新功能来讲的,相比较之前我们一直使用TFS2013来管理团队,确实强大了不少,也更加实用了. 首先,什么是DevOp ...
- Abp Uow 设计
初始化入口 在AbpKernelModule类中,通过UnitOfWorkRegistrar.Initialize(IocManager) 方法去初始化 /// <summary> /// ...
- 剑指Offer——二叉树的深度
题目描述: 输入一棵二叉树,求该树的深度.从根结点到叶结点依次经过的结点(含根.叶结点)形成树的一条路径,最长路径的长度为树的深度. 分析: 二叉树的深度等于其左子树的深度和右子树的深度两个中最大的深 ...
- Linux 下的同步机制
2017-03-10 回想下最初的计算机设计,在单个CPU的情况下,同一时刻只能由一个线程(在LInux下为进程)占用CPU,且2.6之前的Linux内核并不支持内核抢占,当进程在系统地址运行时,能打 ...