1、在单核计算机里,有一个资源是无法被多个程序并行使用的:cpu。
没有操作系统的情况下,一个程序一直独占着全都cpu。
如果要有两个任务来共享同一个CPU,程序员就需要仔细地为程序安排好运行计划--某时刻cpu和由程序A来独享,下一时刻cpu由程序B来独享
而这种安排计划后来成为OS的核心组件,被单独名命为“scheduler”,即“调度器”,它关心的只是怎样把单个cpu的运行拆分成一段一段的“运行片”,轮流分给不同的程序去使用,而在宏观上,因为分配切换的速度极快,就制造出多程序并行在一个cpu上的假象。
2、在单核计算机里,有一个资源可以被多个程序共用,然而会引出麻烦:内存。
在一个只有调度器,没有内存管理组件的操作系统上,程序员需要手工为每个程序安排运行的空间 -- 程序A使用物理地址0x00-0xff,程序B使用物理地址0x100-0x1ff,等等。
然而这样做有个很大的问题:每个程序都要协调商量好怎样使用同一个内存上的不同空间,软件系统和硬件系统千差万别,使这种定制的方案没有可行性。
为了解决这个麻烦,计算机系统引入了“虚拟地址”的概念,从三方面入手来做:
2.1、硬件上,CPU增加了一个专门的模块叫MMU,负责转换虚拟地址和物理地址。
2.2、操作系统上,操作系统增加了另一个核心组件:memory management,即内存管理模块,它管理物理内存、虚拟内存相关的一系列事务。
2.3、应用程序上,发明了一个叫做【进程】的模型,(注意)每个进程都用【完全一样的】虚拟地址空间,然而经由操作系统和硬件MMU协作,映射到不同的物理地址空间上。不同的【进程】,都有各自独立的物理内存空间,不用一些特殊手段,是无法访问别的进程的物理内存的。
3、现在,不同的应用程序,可以不关心底层的物理内存分配,也不关心CPU的协调共享了。然而还有一个问题存在:有一些程序,想要共享CPU,【并且还要共享同样的物理内存】,这时候,一个叫【线程】的模型就出现了,它们被包裹在进程里面,在调度器的管理下共享CPu,拥有同样的虚拟地址空间,同时也共享同一个物理地址空间,然而,它们无法越过包裹自己的进程,去访问别一个进程的物理地址空间。
4、进程之间怎样共享同一个物理地址空间呢?不同的系统方法各异,符合posix规范的操作系统都提供了一个接口,叫mmap,可以把一个物理地址空间映射到不同的进程中,由不同的进程来共享。
5、PS:在有的操作系统里,进程不是调度单位(即不能被调度器使用),线程是最基本的调度单位,调度器只调度线程,不调度进程,比如VxWorks
传统进程相当于一个线程的任务。通常一个进程都拥有若干个线程,至少有一个线程。
调度:传统中:进程是拥有资源的基本单位和独立调度分配的基本单位。引入线程后:线程作为调度和分派的基本单位,进程作为资源拥有的基本单位。线程基本上不再拥有资源,提高系统的并发程度。通过一个进程中的线程切换不会引起进程的切换,但是一个进程中的线程切换到另一个进程中的线程时将会引起进程的切换。
并发性:在引入线程的操作系统中,不仅进程之间可以并发执行,而且在一个进程中的多个线程之间也可以并发执行,从而提高系统资源的利用率和吞吐量。
拥有资源:进程都可以拥有资源,是系统中拥有资源的基本单位,线程自己不拥有系统资源,但是可以访问隶属进程的资源,即一个进程的代码段,数据段及拥有的系统资源。
系统开销:创建和撤销进程时,系统都要为之创建和回收进程控制块,分配或回收资源,如内存空间和I/O设备等,操作系统所付出的开销明显大于线程创建和撤销时的开销。进程的切换 涉及进程CPU环境的保存及新被调度运行进程的CPU环境设置,现成的切换仅需保存和设置少量寄存器内容,不涉及存储器管理方面的操作。同时同一个进程中的多个线程具有相同的地址空间,在同步和通信的实现方面线程也比进程容易。
线程属性:轻型实体,不拥有系统资源,但是有必不可少的,保证其独立运行的资源(控制线程运行的线程控制块TCB,用于指示被执行指令序列的程序计数器,保留局部变量,少数状态参数和返回地址等的一组寄存器和堆栈);独立调度和分派的基本单位:在多线程OS中,线程是独立运行的基本单位也是独立调度和分派的基本单位;可并发执行:在一个进程中的多个线程之间可并发,不同进程中的线程也能并发;共享进程资源:可以访问进程的每个地址,以及进程所拥有的已打开的文件,定时器,信号量机构等。
线程的状态:执行,就绪,阻塞
大多数的线程在中止后并不立即释放所占用资源,只有当进程的其他线程执行了分离函数后被终止的线程才与资源分离,此时的资源才能与资源分离。此时的资源才能被其它线程利用。虽已中止但尚未释放资源的线程,仍可以被需要它额线程所调用,以使被终止线程重新恢复运行。调用者须调用条“等待线程终止”的连接命令,来与线程进行连接。
内核支持线程:内核能够同时调用同一个进程中的多个线程并行执行;如果进程中的一个线程被阻塞了,内核可以调度进程中的其他线程战友处理器运行,也可以运行其他进程中的线程;支持具有很小的数据结构和堆栈,现成的切换和开销小;内核本身为多线程技术,提高系统的执行效率和速度。缺点:模式切换开销大,同一个进程中一个线程切换到另一个进程需要从用户态转换到内核态执行,线程调度和管理是内核实现的系统开销较大。
用户级线程:系统的调度仍是以进程为单位进行,线程切换不需要转换到内核空间,对已个进程而言,所有线程管理数据结构均在该进程的用户空间中。节省内核宝贵资源;调度算法可以是进程专用的,不干扰系统调度;用户级线程的实现与操作系统平台无关。缺点:系统调用的阻塞问题,当一个线程阻塞时,该进程的所有其他线程也阻塞,而内核支持线程则进程中的其他线程仍然可以运行;单纯的用户级线程实现方式中,多线程应用不能利用多处理机进行多重处理的优点,内核每次分给一个进程仅一个CPU,进程中仅一个线程能够执行。
组合方式:有些操作系统把用户级线程和内核支持线程进行组合。ULT/KST