操作系统中的进程与线程
- 格式:doc
- 大小:196.50 KB
- 文档页数:9
操作系统的进程与线程为了对操作系统系统的内部结构原理进行进一步的了解和研究,我们全面介绍了操作系统进程与线程的相关知识。
本文一共分为3部分来讲述,分别是进程,线程,进程与线程区别。
其中各章节里面又包含了操作系统进程引入、概念、特征、状态、进程控制块、操作系统进程操作相关API、线程的引入、概念、组成、属性、线程周期及它的周期图、线程特点、创建线程的方法与区别(针对C/C++/MFC)、进程与线程的区别、进程通信的13种机制、线程同步的一系列知识、线程调度算法的总体描述、操作系统线程的优先级、线程调度数据结构、处理机调度的四个层次、三种典型的线程调度算、对优先级的抽象说明、操作系统支持的优先级类、相对的线程优先级、进程优先级类和线程相对优先级的映射、优先级编程、动态提升线程优先级、计算机结构示意图解析、线程的亲缘性示例。
通过这些知识点的整理和讲解,读者可以融会贯通,更好的深入了解操作系统内部进程线程原理。
1.1 windows进程(Process):1.1.1 进程引入多道程序在执行时,需要共享系统资源,从而导致各程序在执行过程中出现相互制约的关系,程序的执行表现出间断性的特征。
这些特征都是在程序的执行过程中发生的,是动态的过程,而传统的程序本身是一组指令的集合,是一个静态的概念,无法描述程序在内存中的执行情况,即我们无法从程序的字面上看出它何时执行,何时停顿,也无法看出它与其它执行程序的关系,因此,程序这个静态概念已不能如实反映程序并发执行过程的特征。
为了深刻描述程序动态执行过程的性质,人们引入“进程(Process)”概念。
1.1.2 进程概念进程通常被定义为一个正在运行的程序的实例,它由两个部分组成:一个是操作系统用来管理进程的内核对象。
内核对象也是系统用来存放关于进程的统计信息的地方。
另一个是地址空间,它包含所有可执行模块或DLL模块的代码和数据。
它还包含动态内存分配的空间。
如线程堆栈和堆分配空间。
进程是由进程控制块、程序段、数据段三部分组成。
进程是一个具有独立功能的程序关于某个数据集合的一次运行活动。
它可以申请和拥有系统资源,是一个动态的概念,是一个活动的实体。
它不只是程序的代码,还包括当前的活动,通过程序计数器的值和处理寄存器的内容来表示。
1.1.3 进程概念的两个特征拥有资源的单位-进程被分派保存进程映像的续地址空间分派Dispatching (调度)的单位-进程是由一个或多个程序的一次执行可能会与其他进程交替执行对进程两个特征,有些操作系统进行独立处理(改进)分派被称为一个线程(thread)或轻型进程(lightweight process)分派资源被称为进程或任务1.1.4 进程的三种基本状态一个进程的生命周期可以划分为一组状态,这些状态描述了整个进程。
系统根据PCB结构中的状态值控制进程。
在进程的整个生命周期内,一个进程至少具有三种基本状态,它们是:执行状态、等待状态和就绪状态。
这三种状态之间可以相互换,处于就绪状态的进程已经得到除CPU之外的其它资源,只要由调度得到处理机,便可立即投入执行。
处于执行状态的进程因时间片到而放弃处理机进入就绪状态,因等待某个事件发生而放弃处理机进入等待状态。
处于等待状态的进程因等待的事件发生而被唤醒进入就绪状态,如下图:1.1.5 进程控制块进程控制块是由OS维护的用来记录进程相关信息的一块内存数据结构。
每个进程在OS中的登记表项(可能有总数目限制),OS据此对进程进行控制和管理(PCB中的内容会动态改变),不同OS则不同处于核心段,通常不能由应用程序自身的代码来直接访问,而要通过系统调用。
1.1.6 Windows 进程操作相关APICreateProcess():进程创建ExitProcess()或TerminateProcess():进程退出ExitProcess()终止一个进程和它的所有线程;它的终止操作是完整的,包括关闭所有对象句柄、它的所有线程等;TerminateProcess()终止指定的进程和它的所有线程;它的终止操作是不完整的(如:不向相关DLL通报关闭情况),通常只用于异常情况下对进程的终止。
1.2 windows线程(thread):1.2.1 线程的引入是为了提高系统内程序的并发执行程度而提出来的概念,它是比进程更小的能够独立运行的基本单位。
进程是不活泼的。
若要使进程完成某项操作,它必须至少拥有一个线程,该线程负责执行包含在进程的地址空间中的代码。
实际上,单个进程可能包含若干个线程,所有这些线程都“同时”执行进程地址空间中的代码。
为此,每个线程都有它自己的一组CPU寄存器和它自己的堆栈。
每个进程至少拥有一个线程,来执行进程的地址空间中的代码。
当创建一个进程时,系统会自动创建它的第一个线程,称为主线程。
然后,该线程可以创建子线程,而这些子线程又能创建更多的子线程。
1.2.2 线程概念线程,有时被称为轻量级进程(Lightweight Process,LWP),是程序执行流的最小单元。
一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成。
另外,线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。
一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。
由于线程之间的相互制约,致使线程在运行中呈现出间断性。
线程也有就绪、阻塞和运行三种基本状态。
每一个程序都至少有一个线程,若程序只有一个线程,那就是程序本身。
线程是程序中一个单一的顺序控制流程。
在单个程序中同时运行多个线程完成不同的工作,称为多线程。
在多线程OS中,通常是在一个进程中包括多个线程,每个线程都是作为利用CPU的基本单位,是花费最小开销的实体。
1.2.3 线程组成线程也是由两个部分组成的:一个是线程的内核对象,操作系统用它来对线程实施管理。
另一个是线程堆栈,它用于维护线程在执行代码时需要的所有函数参数和局部变量。
1.2.4 线程属性线程具有以下属性:轻型实体、独立调度和分派的基本单位、共享进程资源。
在多线程OS中,线程是能独立运行的基本单位,因而也是独立调度和分派的基本单位。
由于线程很“轻”,故线程的切换非常迅速且开销小。
在一个进程中的多个线程之间,可以并发执行,甚至允许在一个进程中所有线程都能并发执行;同样,不同进程中的线程也能并发执行。
在同一进程中的各个线程,都可以共享该进程所拥有的资源,这首先表现在:所有线程都具有相同的地址空间(进程的地址空间),这意味着,线程可以访问该地址空间的每一个虚地址;此外,还可以访问进程所拥有的已打开文件、定时器、信号量机构等。
1.2.5 线程周期及它的周期图①新建②就绪③运行④阻塞⑤死亡1.2.6 线程特点1.线程都具有一个ID2.线程具有自己的安全属性3.每个线程都有自己的内存栈4.每个线程都具有自己的寄存器信息1.2.7 创建线程的方法与区别(针对C/C++/MFC)1、CreateThread( ) ——WIN32 API函数2、_beginthreadex( ) ——MS对C Runtime库的扩展SDK函数3、AfxBeginThread( ) ——MFC中线程创建的MFC函数CreateThread:提供操作系统级别的创建线程的操作,且仅限于工作者线程。
线程函数中不调用MFC和RTL的函数时,可以用CreateThread,其它情况不要轻易使用,以免内存泄漏。
但它没有考虑:(1)C Runtime库里面有一些函数使用了全局量,如果使用CreateThread 的情况下使用这些C++ 运行库的函数,就会出现不安全的问题。
而_beginthreadex 为这些全局变量做了处理(典型的例子是strtok函数)(2)MFC也需要知道新线程的创建,也需要做一些初始化工作。
_beginthreadex :MS对C Runtime库的扩展SDK函数,首先针对C Runtime库做了一些初始化的工作,以保证C Runtime库工作正常。
然后,调用CreateThread真正创建线程。
仅使用Runtime Library时,可以用_BegingThread。
_beginthreadex函数在创建线程的时候分配了一个堆结构并和线程本身关联起来,这个结构叫做tiddata结构,线程创建时传入的线程入口函数地址就保存在这个结构中;另外,C运行时库中有些函数需要通过这个结构来保存和获取一些数据,比如说errno之类的线程全局变量。
当一个线程调用一个要求tiddata结构的C Runtime库函数的时候,将发生下面的情况:C Runtime库函数试图TlsGetvalue获取线程数据块的地址,如果没有获取到,函数就会现场分配一个tiddata结构,并且和线程相关联,于是问题出现了,如果不通过_endthreadex函数来终结线程的话,这个结构将不会被撤销,内存泄漏就会出现了。
但通常情况下,我们都不推荐使用_endthreadex函数来结束线程,因为里面包含了ExitThread调用。
AfxBeginThread :MFC中线程创建的MFC函数,首先创建了相应的CWinThread对象,然后调用CWinThread::CreateThread,在CWinThread::CreateThread中,完成了对线程对象的初始化工作,然后,调用_beginthreadex(AfxBeginThread相比较更为安全)创建线程。
它简化了操作或让线程能够响应消息,即可用于界面线程,也可以用于工作者线程,但要注意不要在一个MFC程序中使用_beginthreadex()或CreateThread()。
1.3 进程与线程的区别1.3.1 区别的总体论述线程和进程的区别在于,子进程和父进程有不同的代码和数据空间,而多个线程则共享数据空间,每个线程有自己的执行堆栈和程序计数器为其执行上下文。
多线程主要是为了节约CPU时间,发挥利用,根据具体情况而定。
线程的运行中需要使用计算机的内存资源和CPU。
通常在一个进程中可以包含若干个线程,它们可以利用进程所拥有的资源。
在引入线程的操作系统中,通常都是把进程作为分配资源的基本单位,而把线程作为独立运行和独立调度的基本单位。
由于线程比进程更小,基本上不拥有系统资源,故对它的调度所付出的开销就会小得多,能更高效的提高系统内多个程序间并发执行的程度,从而显著提高系统资源的利用率和吞吐量。
1.3.2 进程与线程的区别和联系(1)划分尺度:线程更小,所以多线程程序并发性更高;(2)资源分配:进程是资源分配的基本单位,同一进程内多个线程共享其资源;(3)地址空间:进程拥有独立的地址空间,同一进程内多个线程共享其资源;(4)处理器调度:线程是处理器调度的基本单位;(5)执行:每个线程都有一个程序运行的入口,顺序执行序列和程序的出口,但线程不能单独执行,必须组成进程,一个进程至少有一个主线程。