搞基础系列-Linux系统-进程与线程篇
前言
作为一个Android开发者,可能大部分时间都放在了上层的代码编写和学习上,对于一些基础的东西像操作系统、网络、数据结构与算法还有设计模式可能了解不多,搞基础系列准备以个人的经验为出发,整理一些个人认为比较重要的,对工作有帮助的一些基础知识点,虽不能面面俱到,但力求包含重点常见知识,这不仅是一个分享,也是个人学习的记录和总结。
Linux学习路线
image(这个路线图只是从自己的经验和实际出发得出的,个人觉得在平时可以用到和需要了解的知识,不求面面俱到,只要重点记忆突破。)
1.什么是进程
1.1定义
进程本质上就是一个正在执行程序的实例,包括程序计数器,寄存器和变量的当前值。Linux中,每个进程执行一段独立的程序并且在进程初始化的时候拥有一个独立的控制线程和相应的地址空间。
1.2进程的创建
在Linux中,通过使用fork函数,来创建进程。系统调用fork函数后将会创建一个与原始进程完全相同的进程副本。调用fork函数的进程称为父进程,新的进程称为子进程。父进程和子进程都拥有自己私有的进程映像。
pid=fork();
if(pid<0){
handler_error();//如果pid小于0,说明进程创建失败
}
else if(pid>0){
//父进程代码
}
else{
//子进程代码
}
上面的例子中,这个非0pid就是子进程的进程标识符
父进程和子进程间的变量彼此之间是相互不可见的,因为它们有不同的地址空间,但是父进程和子进程可以共享已经打开的文件。
2.什么是线程
2.1线程定义
线程与进程的定义几乎是一致的,除了同一进程中的多个线程共享相同的地址空间。
2.2为什么需要多线程
(1)线程同进程一样,是一个概念模型,在同一进程中,通过线程我们可以实现并发的执行逻辑,这是有实际需要的,比如你发起一个网络请求,但是同时展示一个加载页面
(2)线程相对进程更加轻量级,线程的创建和撤销相比进程更加快速和容易
(3)对于单cpu来说,多线程中每个线程如果都是cpu密集型的,那么并不能获得性能上的增强,如果存在大量的I/O处理,多线程允许活动彼此重叠进行,从而加快应用执行速度
(4)在多cpu系统中,多线程实现了真正的并行,并不是单cpu中的那种伪并行(单个cpu通过切换让出时间给某个线程直线,以此模拟并行的情况,实际上某个时间点只有一个线程执行,也就是所谓的宏观并行,微观串行)
2.3用户级线程,内核级线程和混合线程
2.3.1用户级线程:
(1)线程所有的操作都由线程库来完成,因为无需陷入内核,所以效率较高
(2)内核不感知线程,还是已单进程来处理,可以让不支持多线程的操作系统实现多线程
(3)内核资源的分配仍然是按照进程进行分配的;各个用户线程只能在进程内进行资源竞争。
2.3.2内核级线程:
(1)线程的创建、撤销和切换等,都需要内核直接实现,即内核了解每一个作为可调度实体的线程。
(2)这些线程可以在全系统内进行资源的竞争。
2.3.3混合线程
用户级线程和内核级线程的集合
image一图胜千言
3.进程与线程的区别
进程是各种资源的合集,进程用于把资源集中在一起,而线程则是在CPU上被调度执行的实体。
4.通信
4.1进程间通信方式
在Linux中进程间通信有共享内存、管道、UNIX Domain Socket和RPC四种
4.2同步机制
常见的比较经典的有信号量、Mutex、管程和Linux Futex
(通信这一部分设计内容比较多,这里只是简单介绍一下方式,之后出一篇博客来详细进行讲解)
5.调度算法
不同类型的操作系统会采用不同的调度算法,常见的有先来先服务、轮转调度、优先级调度、彩票调度等。在Linux中,因为Linux系统中的线程是内核线程,所以Linux系统的调度是基于线程的,而不是基于进程的。
Linux的调度器成为完全公平调度器(CFS)
CFS采用红黑树作为调度队列的数据结构。根据任务在CPU上运行的时间长短而将其有序的排列在树中,这种时间称为虚拟运行时间。
CFS算法总结如下:优先调度哪些使用CPU时间最少的任务,就是红黑树的最左节点上的任务。周期性的根据任务已经运行的时间,递增它的虚拟运行时间值,并将这个值与树中最左节点进行比较,如果当前最左节点虚拟运行时间依旧最短,那么它将继续执行,否则将进行树的旋转,将原先的最左节点放置到其他位置,然后依旧执行最左节点。
6参考
《现代操作系统》
image关注我的公众号