Download presentation
Presentation is loading. Please wait.
1
互斥与同步 操作系统实验2
2
内容 一、信号量机制解决互斥与同步问题 实验:P/V信号量的编程实现 二、管程机制解决互斥与同步问题 实验:管程机制的编程实现
3
一、信号量机制解决互斥与同步问题
4
信号量机制 信号量(semaphore)机制 解决并发进程同步的工具 P操作表示同步进程发出的检测信号量操作,检测是否能够使用临界资源
V操作表示访问完临界资源的进程通知等待进程已经完成了临界资源的访问,将临界资源释放。
5
经典互斥与同步问题回顾 生产者-消费者问题 读者-写者问题 哲学家进餐问题
6
生产者-消费者问题 生产者P: 消费者C: Wait(empty); Wait(mutex); Buffer(in)=nextp;
mutex,full,empty:semaphore mutex :=1; full:=0; empty:=n; 生产者P: Wait(empty); Wait(mutex); Buffer(in)=nextp; in:=(in+1) mod n; Signal(mutex); Signal(full); 消费者C: Wait(full); Wait(mutex); netxc=buffer(out); out:=(out+1) mod n; Signal(mutex); Signal(empty);
7
读者-写者问题(读者优先) 读者R: 写者W: rcount++; if(rcount == 1) Wait(wmutex);
Wait(rmutex); rcount++; if(rcount == 1) Wait(wmutex); Signal(rmutex); Read_Action(); rcount--; if(rcount == 0) Signal(wmutex); rmutex,wmutex:semaphore rmutex :=1;wmutex :=1; rcount:int rcount:=0; 写者W: Wait(wmutex); Write_Action(); Signal(wmutex);
8
哲学家进餐问题 哲学家i(i=0,1..5) thinking(); Wait(fork[i]);
Wait(fork[(i+1) mod 5]) eating(); Signal(fork[i]); Signal(fork[(i+1) mod 5]) array of fork[]:semaphore fork[] :={1,1,1,1,1}; 思考,怎么解决 死锁问题 ?
9
同步对象 同步对象是指Windows/Linux中用于实现同步与互斥的实体, 包括互斥量(Mutex)、信号量(Semaphore)、临界区(Critical Section)和事件(Events)等。 本实验中使用到信号量、互斥量和临界区三个同步对象。
10
实验方案设计 以读者-写者(读者优先)为例: 1.创建若干线程分别模拟读者操作和写者操作
2.读线程间和写线程间对各自局部共享资源的访问修改采用 Mutex对象,结合WaitForSingleObject 保证互斥操作。 3.读线程与写线程争用全局临界资源采用临界区(Critical Seciton)。 4.统管读写线程的线程采用WaitForMultipleObjects 保证等待所有的线程结束。
11
创建线程函数 CreateThread 功能:该函数创建一个在调用进程的地址空间中执行的线程。
若函数调用成功,返回值为新线程的句柄;若函数调用失败, 返回值为NULL。 格式: HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, DWORD dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlag, LPDWORD lpThreadId); 参数说明: lpThreadAttributes—指向一个LPSECURITY_ATTRIBUTES(新线程的安全性描述符)。 dwStackSize—定义原始堆栈大小。 lpStartAddress—指向使用LPTHRAED_START_ROUTINE类型定义的函数。 lpParamiter—定义一个给进程传递参数的指针。 dwCreationFlags—定义控制线程创建的附加标志。 lpThread—保存线程标志符(32位)
12
退出线程函数 ExitThread 功能:该函数结束一个线程 格式:VOID ExitThread (DWORD dwExitCode);
参数说明: dwExitCode—调用线程的退出代码
13
创建互斥量函数 CreateMutex 功能:函数创建有名或者无名的互斥对象。如果函数调用成功,返回值
是互斥对象句柄;如果函数调用之前,有名互斥对象已存在,那么函数 给已存在的对象返回一个句柄。 格式: HANDLE CreateMutex(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCTSTR lpName); 参数说明: lpMutexAttributes—取值NULL。 bInitialOwner—指示当前线程是否马上拥有该互斥量(即马上加锁)。 lpName—互斥量名称。
14
释放互斥量函数 ReleaseMutex 功能:释放互斥对象的控制权。 格式:
BOOL WIANPI ReleaseMutex(HANDLE hMutex); 参数说明: hMutex—互斥对象句柄。 返回值:TRUE表示成功,FALSE表示失败。 注:相当于我们的V操作
15
创建信号量函数 CreateSemaphore 功能:创建一个新的信号量。 格式: HANDLE CreateSemaphore(
LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, LONG lInitialCount, LONG lMaximumCount, LPCTSTR lpName); 参数说明: lpSemaphoreAttributes——用于定义信号量的安全特性。 lInitialCount——设置信号量的初始计数。 lMaximumCount——设置信号量的最大计数。 lpName——指定信号量对象的名称。
16
释放信号量函数 ReleaseSemaphore 功能:函数用于对指定的信号量增加指定的值。
格式:BOOL ReleaseSemaphore( HANDLE hSemaphore, LONG lReleaseCount, LPLONG lpPreviousCount); 参数说明: hSemaphore——所要释放的信号量句柄。 lReleaseCount——所要释放信号量的数目。 lpPreviousCount——指向返回信号量上次值的变量的指针,如果不需要信号量 上次的值,那么这个参数可以设置为NULL。 注:相当于我们的V操作
17
使用临界区资源的相关函数 VOID InltlallzeCriticalSection(
LPCRITICAL_SECTION IpCritiCalSection); 函数功能:该函数初始化临界区对象。返回值:无。 VOID EnterCriticalSection( LPCRITICAL_SECTION lpCriticalSection); 函数功能:该函数是等待指定临界区对象的所有权。当调用线程被 赋予所有权时,该函数返回。返回值:无。 VOID LeaveCriticalSection( 函数功能:该函数释放指定临界区对象的所有权。返回值:无。
18
等待同步对象函数 WaitForSingleObject 功能:使程序处于等待状态,直到信号量hHandle出现(即其值大于
等于1)或超过规定的等待时间。 格式: DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds); 参数说明 hHandle——同步对象指针。 dwMilliseconds——等待的最长时间(INFINITE为无限等待)。 注:相当于我们的P操作
19
等待所有线程完成函数 waitForMultipleObjects
功能:WaiForMultipleObjects函数当下列条件之一满足时返回: (1)任意一个或全部指定对象处于信号态; (2)超时间隔已过。 格式:DWORD waitForMultipleObjects (DWORD nCount, CONST HANDLE * lpHandles, BOOL fWaitAll, IDWORD dwMilliSeconds) ; 参数说明: nCount——句柄的数量 最大值为MAXIMUM_WAIT_OBJECTS(64) HANDLE——句柄数组的指针。 HANDLE 类型可以为(Event,Mutex,Process,Thread,Semaphore ) 数组 bWaitAll ——等待的类型,如果为TRUE 则等待所有信号量有效在往下执行, FALSE 当有其中一个信号量有效时就向下执行。 dwMilliseconds——超时时间 超时后向执行。 如果为WSA_INFINITE 永不超时。如果没有信号量就会在这死等。
20
输入数据格式及运行效果 提示:由于牵涉格式的问题,最好在文件中读取输入数据。 测试数据文件的例子: 1 R 3 5 2 W 4 5
21
代码实例-初始化操作
22
代码实例-主线程
23
代码实例-主线程
24
代码实例-读者线程
25
代码实例-写者线程
26
思考 试把控制读/写的全局临界资源用Critical Section换成互斥量mutex,看看实验结果有什么变化,并且查阅相关资料说明原因。
27
实验内容 题目1:用PV信号量实现读者-写者问题(写者优先)程序。 题目2:用PV信号量实现生产者与消费者问题。
28
实验要求 1.每人做一道题 2.学号末2位模4所得结果+1为该生所做题目号
Similar presentations