第二章多任务和多线程_第1页
第二章多任务和多线程_第2页
第二章多任务和多线程_第3页
第二章多任务和多线程_第4页
第二章多任务和多线程_第5页
已阅读5页,还剩26页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第二章多任务和多线程第一页,共三十一页,2022年,8月28日1.程序的顺序执行所具有的特点:

顺序性

当程序在处理机上运行时,处理机严格的按照顺序执行程序的规定动作

封闭性

一个程序在执行时独占资源,除了开始状态外,只有程序本身规定的动作才能改变资源的状态.

可再现性

程序执行的结果与执行速度无关

第二页,共三十一页,2022年,8月28日2.多道程序设计技术

程序的并发执行

在任一时刻,系统中不再只有一个活动,而且还存在着并行的活动.从硬件方面看,处理机,各种外设,存储部件常常是并行的工作;从程序活动来看则可能有若干作业程序或者同时或者相互穿插的在系统中被执行.

资源共享

这是现代操作系统的另一特性.指系统中的硬件资源和软件资源不再为单个用户程序所独占,而由几个用户程序共同占有.

总之,程序的并发执行和资源共享是相互依存的.第三页,共三十一页,2022年,8月28日3.程序并发执行的特点

失去了程序的封闭性

在任何时刻,程序的执行结果不一致

程序和机器执行的活动不再一一对应

程序:指令的有序集合——静态概念

机器执行程序的活动:指令序列在处理机上的执行活动,通常称之为"计算".——动态概念

【注】在顺序执行的程序中,二者一一对应.

并发程序间的相互制约

主要表现在,一个正在执行的程序需要另一个程序执行的结果的情况.第四页,共三十一页,2022年,8月28日4.进程

在多道程序下,程序的并发执行代替了程序的顺序执行.程序活动不再处于一个封闭系统,而出现了许多新的特征,即独立性,并发性,动态性以及它们之间的相互制约性.

20世纪60年代中期MULTCS系统的设计者和以E.W.Dijkson为首的The系统的设计者开始广泛的使用"进程"这一概念来描述系统和用户的程序的活动.

对于"进程",目前尚无一个非常确切的概念,为了强调进程的并发性和动态性,我们定义"进程"为:

进程是程序的一次执行,该程序可与其他程序并发执行.

第五页,共三十一页,2022年,8月28日注:THE系统是1968年由E.W.Dijkstra和他的学生在荷兰的艾恩德霍文技术学院(TechnischeHogeschoolEindhoven)开发的.此系统中第一次提出了操作系统的层次式结构设计方法.该系统是运行在荷兰的ElectrologicaX8计算机上的一个简单批处理系统,其内存只有32K,每字27位,系统共分6个层次。处理器分配在第0层中进行,在中断发生或定时器到期时,由该层进行切换。在第0层之上,系统由一些连续的进程组成,编写这些进程时不用再考虑在单处理机上多个进程运行的细节。换句话说,第0层中提供了基本的CPU多道程序设计。存储管理在第1层中进行,它为进程分配主存空间,在主存用完时则在一个512K的磁鼓上保留进程的一部分(页面)。第1层上,进程不用考虑它是在磁鼓上还是在主存中运行;第1层软件保证一旦需要访问某一页面时,该页面必定已在内存中。第2层处理进程与操作员控制台之间的通信。在第2层上,可以认为每个进程都有自己的操作员控制台。第3层管理I/O设备和缓存相关的信息流。第3层上,每个进程都与有良好特性的抽象I/O设备打交道,而不必考虑外部设备的物理细节。第4层是用户层。用户进程不用考虑进程,内存,控制台或I/O设备等细节。系统操作员进程位于第5层中。

第六页,共三十一页,2022年,8月28日4.1进程的表示

组成:

程序:描述了进程所要完成的功能

数据集合:包括程序在执行时所需要的数据和工作区

进程控制块(PCB):包含了进程的描述信息和控制信息,是动态特性的集中反映

PCB

程序

数据

PCB

程序

数据

共享

程序段

第七页,共三十一页,2022年,8月28日4.2进程的基本调度状态

运行状态:进程已获得必要的资源,并占有处理机,处理机正在执行该线程.

就绪状态:已具备了运行条件等待处理机.

阻塞状态:进程在运行过程中,应等待某一时间而暂时不能运行的状态.

状态转换关系如下图所示:

调度时间片I/O

用完请求

I/O完成

运行

就绪

阻塞

第八页,共三十一页,2022年,8月28日4.3常用的进程调度算法

静态优先级法

系统在调度进程时,按事先指定的优先级从高到低进行选择

动态优先级

按照变化情况对各个进程的优先级进行适当的调整

时间片轮转

系统把所有的就绪进程按FCFS(FirstComeFirstSever)规则排成一个队列,首先将处理机分配给队列中的第一个进程,并规定执行一定的时间,该时间称为时间片.当该进程用完这一时间片时,系统将它送至就绪队列的所有进程,又把处理机分配给下一进程,再执行同样大小的时间片.这样,就绪队列中的所有进程,就可以依次轮流获得一个时间片的处理时间,然后系统又回到队列的开始部分.如此不断循环.

第九页,共三十一页,2022年,8月28日5.线程

在操作系统中引入"进程"的概念的目的在于提高系统效率,提高系统资源利用率.

进程是系统调度的基本单位,也是系统资源分配的一般单位.进程因创建而产生,经调度程序的调度而运行,因等待某一事件而阻塞,最后因任务完成而撤消.

在进程的整个生存期内要不断地改变进程的运行环境.因此,如果以进程为系统调度的基本单位,要付出较大的时空开销,从而也限制了进程的开销和切换的效率.

为了提高系统的并行能力,把并行程序进一步减小,在进程内部引入了线程(Thread).

线程是系统系统调度的一般单位,而不是独立资源分配的基本单位.

线程可定义为"进程内的一个执行单位",或者定义为"进程内的一个可调度的实体.一个进程可以有多个线程,而且至少有一个可执行线程.

第十页,共三十一页,2022年,8月28日5.1进程和线程的关系

进程和线程是构造操作系统的两个基本元素,是操作系统的两个活动部分,两者之间的关系如下:

1.线程是进程一个组成部分.

2.进程的多线程都在进程的地址空间活动.

3.资源是分配给进程的,而不是分配线程的.线程在执行中需要资源是,系统从进程的资源配额中扣除并分配给它.

4.处理机调度的基本单位是线程.

5.线程在执行过程中,需要同步.

第十一页,共三十一页,2022年,8月28日5.2线程的组成

WindowsNT中,线程和进程一样,也用对象来实现.线程是对象管理程序创建和删除.

一个线程的基本组成是:

(1)一个唯一的标识符,称之为客户ID.

(2)描述处理机状态的一组寄存器内容.

(3)两个栈,分别用于用户态和核心态下执行.

(4)一个私用的存储区.

第十二页,共三十一页,2022年,8月28日5.3线程的基本调度状态

(1)就绪状态:该线程已具备执行条件以等待CPU的执行,线程调度程序只从就绪线程池中选择线程进入备用状态.

(2)备用状态:系统中每个处理机上只能有一个线程处于备用状态.处于备用状态的线程已被选定某一特定处理机的一个执行对象.当条件合适时,调度程序为该线程进行描述表切换.

(3)运行状态:一旦调度程序执行完描述表切换,该线程便进入了运行状态.

(4)等待状态:以下情况可使线程进入等待状态:线程等待某一对象(事件)以便同步它的执行;因I/O系统而等待;环境子系统导致线程自己阻塞.当线程的等待结束,就回到就绪状态.

(5)转化状态:如果线程已准备好执行,但由于资源不可用,从而成为转化状态.当资源为可用时,线程便于由转化状态进入就绪状态.

(6)终止状态:线程完成了它的执行.

第十三页,共三十一页,2022年,8月28日5.4线程之间的通讯

进程是没有活力的,它只是一个静态的概念.一个程序运行时,由系统自动创建一个进程.一个进程至少拥有一个线程,即主线程.主线程以函数地址形式提供给操作系统.主线程终止,进程亦终止.另外,根据需要在程序中可以自己创建其他线程,称之为次线程.

一般情况下,一个次级线程要为主线程完成某种特定类型的任务,这就隐含着表示在主线程和次级线程之间需要通信.实现这种通信功能的方法有:

使用全局变量,使用消息和使用事件同步对象5.5线程间通讯的方法(一)

使用全局变量进行线程通信//MyThreadView.cpp......volatileintThreadFlag;;//创建全局变量

第十四页,共三十一页,2022年,8月28日......voidCMyThreadView::OnStopThread(){

ThreadFlag=0;//设置线程标记为终止

}voidCMyThreadView::OnStartThread(){

ThreadFlag=1; HWNDhWnd=GetSafeHwnd(); AfxBeginThread(ThreadProc,hWnd);}第十五页,共三十一页,2022年,8月28日UINTThreadProc(LPVOIDparam){...... for(;;)//无限循环,使秒针不停地旋转 {

//监视全局变量ThreadFlag,若值为零则结束线程 if(ThreadFlag==0)break;......}第十六页,共三十一页,2022年,8月28日使用消息

首先,用户要定义一个用户消息,如下所示:

#defineWM_USERMSGWMUSER+100

然后,需要时在一个线程中可以调用Win32API函数PostMessage()或成员函数CWinThread::PostThreadMessage()向另外一个线程发送定义的消息WM_USERMSG第十七页,共三十一页,2022年,8月28日实例:1.首先定义一个用户消息//MyThreadView.h......constWM_THREADENDED=WM_USER+100;classCMyThreadView:publicCView{......afx_msgLONGOnThreadEnded(WPARAMwParam,LPARAMlParam); DECLARE_MESSAGE_MAP()};第十八页,共三十一页,2022年,8月28日2.消息映射//MyThreadView.cppBEGIN_MESSAGE_MAP(CMyThreadView,CView) //{{AFX_MSG_MAP(CMyThreadView) ON_COMMAND(ID_StartThread,OnStartThread) ON_COMMAND(ID_StopThread,OnStopThread) //}}AFX_MSG_MAP

ON_MESSAGE(WM_THREADENDED,onThreadEnded)

END_MESSAGE_MAP()第十九页,共三十一页,2022年,8月28日3.调用函数::PostMessage()发送消息//MyThreadView.cppUINTThreadProc(LPVOIDparam){......

::PostMessage((HWND)parma,WM_THREADENDED,0,0); return0;}第二十页,共三十一页,2022年,8月28日4.手工编写函数OnThreadEnded//MyThreadView.cppLONGCMyThreadView::OnThreadEnded(WPARAMwParam,LPARAMlParam){ CStringstr; str.Format("%s%d%s","第",ThreadCount--,"个线程终止"); MessageBox(str); return0;}第二十一页,共三十一页,2022年,8月28日5.5线程间通讯的方法(二)

使用事件同步对象

多线程程序需要使用同步对象来实现同步.同步对象主要有3种:

临界区对象、互斥(mutex)和信号灯(semaphore).

临界区对象方法:使用临界区对象,将一段代码放入临界区,制止多于一个线程同时进入临界区中CCriticalSectioncriSect;criSect.Lock();criSect.Unlock();第二十二页,共三十一页,2022年,8月28日voidCMainFrame::OnSynchro()//同步方式启动三个线程{ count=0; HWNDhWnd=GetSafeHwnd(); AfxBeginThread(SynchroFunction,hWnd); AfxBeginThread(SynchroFunction,hWnd); AfxBeginThread(SynchroFunction,hWnd);}第二十三页,共三十一页,2022年,8月28日UINTSynchroFunction(LPVOIDparam)//同步线程控制函数{ intData[5],i;

critical.Lock();//保护临界区数据 for(i=0;i<3;i++) { count++; ::Sleep(50); Data[i]=count; } charstr[50]; str[0]=0; for(i=0;i<3;i++) { intlen=strlen(str); wsprintf(&str[len],"%d",Data[i]); }

critical.Unlock();//释放该线程对临界区的控制权 ::MessageBox((HWND)param,str,"NonsynThread",MB_OK); return0;}第二十四页,共三十一页,2022年,8月28日UINTNonsynFunction(LPVOIDparam)//非同步线程控制函数{ intData[5],i; for(i=0;i<3;i++) { count++; ::Sleep(50); Data[i]=count; } charstr[50]; str[0]=0; for(i=0;i<3;i++) { intlen=strlen(str); wsprintf(&str[len],"%d",Data[i]); } ::MessageBox((HWND)param,str,"NonsynThread",MB_OK); return0;}第二十五页,共三十一页,2022年,8月28日voidCMainFrame::OnNonsyn()//非同步方式启动三个线程{ count=0; HWNDhWnd=GetSafeHwnd(); AfxBeginThread(NonsynFunction,hWnd); AfxBeginThread(NonsynFunction,hWnd); AfxBeginThread(NonsynFunction,hWnd);}第二十六页,共三十一页,2022年,8月28日互斥对象(Mutexse):类似临界区对象,如果另一线程已经占用了互斥对象,系统将挂起当前的调用线程,直到这个互斥对象被占用线程释放为止CSingleLocksingleLock(&mutex);singleLock.Lock();singleLock.Unlock();第二十七页,共三十一页,2022年,8月28日//MySyn1View.cpp//CCriticalSectioncritical;CMutexmutex;UINTSynchroFunction(LPVOIDparam)//同步线程控制函数{......

//critical.Lock();//保护临界区数据 CSingleLocksingleLock(&mutex);//用互斥对象保

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论