序言:
我们知道多线程是现代操作系统中一个很重要的组成部分。它经常在面试过程中或者在实际运用过程中都会碰到的一个比较难的一个问题,所以这篇文章所属的一个系列,将浅显的记录下博主的多线程学习的一个过程。
首先呢,说起线程的起源,我们不得不提就是进程的概念。然而一开始也并不是直接就有的进程的,而是由多道处理程序环境下,演化而来的。
由于多道程序有间断性和失去封闭性、以及不可再现性,催生出了进程的产生。浅显的来说,进程就可以能使程序并发的执行程序,并加以描述和控制。这又是为什么呢?因为其中有一个专门的数据结构称为进程控制块。那么什么是进程?又是进程控制块呢?什么又是线程呢?如何处理多线程呢?我们接着看下去。
一. 为什么要引入进程
这个部分可以分两个部分来看:
1.在20世纪60年代中期,IBM开发了OS/360操作系统是第一个多道程序的批处理系统,在引入程序间的并发执行功能后,虽然提高了系统的吞吐量和资源的利用率,但同时也带来了一系列的问题:(1)间断性。程序在并发执行时,由于它们共享系统资源,它们之间必将会形成互相制约的关系。(2)失去封闭性。当系统中存在着多个以可以并发执行的程序时,系统中的各种资源将为他们所使用。这就意味着其中一个程序在运行时。其环境都必然会受到其他程序的影响。这不同于我们现在对操作系统已有的观念,其实这有点儿像多线程中对共享变量不加锁的情况。(3)不可再现性。一段程序的执行出现了多种可能,而且出现了不确定性。我们知道程序的确定性是一个基本的要素。
2.我们进一步来看待这一个问题。在第一点中我们提到了资源利用率和系统吞吐量的问题,并且间断性的原因在于它们之间互相制约。这又是为什么呢?这是因为我们计算机的存储层次结构之间访问速率不匹配的原因造成的。CPU的速度比内存快,内存比硬盘快,硬盘又比读取网络资源快。为解决这个问题,操作系统就由此诞生了。一旦开机后,操作系统进入内存,它就是老大了。对我们计算机一个全局的掌控。它自带各种算法,其目的是寻找到一个中庸之道,让我们的计算机得以平衡和稳定地运行。进程就是在操作系统演化过程中产生的。进程也服从操作系统一系列规则运行。
二.进程的定义
首先,进程可以简单的定义为一个正在执行中的程序。举个例子:JVM是一个进程,QQ是一个进程,浏览器是一个进程等等。我们可以打开任务管理器可以看到,我们的电脑运行着很多很多的进程。
同时我们又可以看到CPU的利用率是忽高忽低的,这是为什么呢?
肯定不是因为抽风,而是因为在操作系统的管理下,由进程调度算法,不断地有进程在内存中换进换出,进程的执行是要占有CPU的,一个CPU同一时刻只能运行一个进程中的某一指令,进程有时候占用CPU多,有时候占用CPU少。不同的进程,所需要的CPU等资源也就是不一样的。所以就出现了这样一个现象。不光如此,进程执行的同时,也要消耗计算机的各种资源:CPU、内存、网络、IO、文件系统。
所以这说明了两点:进程是拥有资源的独立单位。进程同时又是一个可独立和分派的基本单位。
然后,我们再具体说明进程的概念:一个具有独立功能的程序在一个数据集合上的一次动态执行的过程。
三. 进程的组成
程序的代码
程序处理的数据
要知道现在执行哪条指令,程序计数器PC中的值指示将运行的指令。
CPU寄存器会动态变化,一组通用寄存器的当前值,堆,栈等;
各种系统资源,内存,外存,网络。
包含了正在运行的一个程序的所有状态信息,这些信息基本都记录在进程控制块PCB(Process Control Block)中:
四. 进程的特点
进程等待(阻塞):三种情况:(1)请求并等待系统服务,无法马上完成;
(2)某种操作(和其他进程协调工作),无法马上完成;(3)需要的数据没有到达
进程自己触发阻塞,因为只有自己才知道何时需要等待某事件 。进程只能自己阻塞自己。
进程唤醒:需要的资源可被满足,等待的事件到达,都意味着可将该进程的PCB插入到就绪队列 。注意,被唤醒后不能立即执行,需要进入到就绪状态,等待占有CPU。因为自身没有占用cpu执行,所以只能被OS或其他进程唤醒
进程结束:结束情况:自愿(正常退出,错误退出),强制性的(致命错误,被其他进程所杀)
综上我们称之为五状态图:
其中多了一条运行到就绪状态,因为该进程时间片用完了,就绪对列有很多需要处理,所以CPU只分配一点点时间给每一个进程。操作系统让它退出了CPU,等待再次被调度。同时操作系统根据线程优先级加之调度算法调度其他线程。首先是操作系统调度器完成调度。操作系统时钟在起作用:知道执行了多久,一旦超时,操作系统就会得到感知,运行态的进程就会停下来,变成就绪态,再选择一个就绪太的进程占用CPU来执行。
PS:关于调度算法又是一门学问了,我们之后再讲,先占坑。
接着我们有七状态图:引入进程挂起,和进程激活。