单道程序进化为多道程序?
单道程序:一个程序去取数据的时候,CPU都会先为它一个服务,这段取数据的时间cpu是需要等待的,直到这个程序运行结束。
多道程序:一个程序去取数据的时候,CPU不会傻等了,它会先不鸟它,看看其他程序需不需要服务。
那么多道程序如何进化为进程呢?
如果qq拜托IO子系统去帮他看看键盘打了什么字,在拜托的这段时间,他想着自己反正也用不着cpu,就主动放弃,那么360就可以去使用cpu了。之后360或者其他程序的情况都和qq的类似。他们每个程序都可能会去取键盘输入的值,也有可能不会。如果去取的话,那么cpu就会重新进行分配。
下面我们看一下多道程序中cpu分配流程图:
排队的人有两种:阻塞的话就是IO中,就绪的话就是IO完。如果阻塞的人获得cpu那么发现自己还没准备好,就马上放弃。就绪的人获得cpu就可以直接运行了。
为了让cpu的利用更高效,所以排队的队列应该分为两种,一列是准备好的人,一列是没准备好的人。如果是因为cpu时间到了而不是IO阻塞放弃的cpu,那么直接进入就绪队列。
当cpu空闲的时候,准备好的人去获取,那么阻塞的人就不会获得,提高cpu利用率。
我们把上面的图抽象一下:
那么这个时候进程就出来了:进程=程序+PCB
进程怎样进化为线程?
我们先来看一下一个程序如果只有进程没有线程的话运行效果是怎样的?
qq,360,lol如果之为他们开一个进程去实现他们所有的功能
一个进程去完成这4个功能,会造成一种卡顿的效果。这个时候4个功能是共用一个cpu的,只能一个一个的来。网络功能用的时候其它三个就得等待。
既然一个进程会卡的话,那我为每个功能都分配一个进程。
当网络卡的时候,我还可以进行键盘输入,鼠标移动,渲染等功能。
虽然他也能解决卡顿的问题,但是时空开销非常大,每个进程都得建立PCB档案。在操作系统中PCB档案资源是非常有限的。并且进程之间cpu切换的时候,也会导致时间和空间的开销-上下文切换。
时间上:假设有10000个进程,那么每次切换cpu都得去10000个PCB里面寻找到属于qq的PCB,然后修改他的状态。
空间上:假如qq的代码执行到第500行,要记住qq此时程序执行状态,就需要栈来装这些代码。然后cpu切换到lol去执行。等回来的时候,cpu继续去栈中读取第501行代码往下执行。
为了避免PCB过多,时空开销过大的情况。我们就引出了线程的概念。
那么线程是怎样工作的呢?
把每个功能看做一个线程,所有的功能组合起来就是一个进程
这样进程数量变少了,PCB也少了。并且由于进程少了,CPU的切换也少了。进程在操作系统资源分配的基本单位,好好理解这句话,也就是说CPU操作的对象是进程。CPU的切换是在进程之间的。
进程是线程的容器,进程和线程是同时存在的。这个就有了两层的的并发,进程和进程之间,线程和线程之间。