操作系统-创建线程,利用互斥实现线程共享变量通信_第1页
操作系统-创建线程,利用互斥实现线程共享变量通信_第2页
操作系统-创建线程,利用互斥实现线程共享变量通信_第3页
操作系统-创建线程,利用互斥实现线程共享变量通信_第4页
操作系统-创建线程,利用互斥实现线程共享变量通信_第5页
已阅读5页,还剩5页未读 继续免费阅读

下载本文档

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

文档简介

1、 2016-2017学年度第一学期大作业  课程名称: 操作系统(含课程设计) 任课教师: 解 晓 萌 作业题目: 创建线程,利用互斥实现线程共享变量通信 姓名: 鲁 斌 学 号: 201515572013002 专 业: 计算机科学与技术 教学中心: 宝 安 学 文 联系电话:        评审日期_成绩_评审教师(签名)_华南理工大学网络教育学院 “计算机操作系统”课程设计大作业 实验报告一、题目: 创建线程,利用互斥实现线程共享变量通信二、目的掌握线程创建和终止,加深对线程和进程概念的理解,

2、会用同步与互斥方法实现线程之间的通信。三、概述:为了确保读线程读取到的是经过修改的变量,必须在向变量写入数据时禁止其他线程对它的任何访问,直至赋值过程结束后再解除对其他线程的访问限制。这保证了线程了解其他线程任务处理结束后的结果而采取的保护措施称为线程同步。从大的方面来讲,线程的同步分为用户模式的线程同步和内核对象的线程同步。用户模式中线程的同步方法有原子访问和临界区等方法。它的特点是同步速度特别快,适合对线程运行速度有严格要求的场合。内核对象的线程同步由事件、等待定时器、信号量以及信号灯等内核对象构成。由于这同步机制使用了内核对象,使用时一定要将线程从用户模式切换到内核模式,而这种转换一般要

3、耗费近千个CPU周期,所以同步速度较慢,但适用性却要远优于用户模式的线程临界区临界区是一段独占对某些共享资源访问的代码,在任意时刻只允许一个线程对共享资源进行访问。通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问若有多个线程试图同时访问临界区,那么在有一个线程进入后其他所有试图访问此临界区的线程将被挂起,并一直持续到进入临界区的线程离开。临界区在被释放后,其他线程可继续抢占,并以此达到用原子方式操作共享资源的目的。使用临界区保持线程同步以下是通过一段代码说明了临界区在保护多线程访问共享资源中的作用。通过两个线程分别对全局变量g_cArray10进行写入操作,用临界区结构对

4、象g_cs来保持线程的同步,并在开启线程前对它进行初始化。为了使实验效果更明显,体现出临界区的作用,在线程函数对共享资源g_cArray10的写入时,以Sleep()函数延迟1毫秒,令其他线程同它抢占CPU的可能性加大。若不用临界区对它进行保护,则共享资源数据将被破坏,但使用临界区对线程保持同步后就可得到正确的结果。代码如下:/ 临界区结构对象CRITICAL_SECTION g_cs;/ 共享资源char g_cArray10;UINT ThreadProc10(LPVOID pParam)/ 进入临界区EnterCriticalSection(&g_cs);/ 对共享资源进行写入操

5、作for (int i = 0; i < 10; i+)g_cArrayi = 'a'Sleep(1);/ 离开临界区LeaveCriticalSection(&g_cs);return 0;UINT ThreadProc11(LPVOID pParam)/ 进入临界区EnterCriticalSection(&g_cs);/ 对共享资源进行写入操作for (int i = 0; i < 10; i+)g_cArray10 - i - 1 = 'b'Sleep(1);/ 离开临界区LeaveCriticalSection(&g

6、_cs);return 0;/ 临界区结构对象CRITICAL_SECTION g_cs;/ 共享资源 char g_cArray10;UINT ThreadProc10(LPVOID pParam)/ 进入临界区EnterCriticalSection(&g_cs);/ 对共享资源进行写入操作for (int i = 0; i < 10; i+)g_cArrayi = 'a'Sleep(1);/ 离开临界区LeaveCriticalSection(&g_cs);return 0;UINT ThreadProc11(LPVOID pParam)/ 进入临界

7、区EnterCriticalSection(&g_cs);/ 对共享资源进行写入操作for (int i = 0; i < 10; i+)g_cArray10 - i - 1 = 'b'Sleep(1);/ 离开临界区LeaveCriticalSection(&g_cs);return 0;void CSample08View:OnCriticalSection()/ 初始化临界区InitializeCriticalSection(&g_cs);/ 启动线程AfxBeginThread(ThreadProc10, NULL);AfxBeginThr

8、ead(ThreadProc11, NULL);/ 等待计算完毕Sleep(300);/ 报告计算结果CString sResult = CString(g_cArray);AfxMessageBox(sResult);信号量内核对象信号量内核,允许多个线程在同一时刻访问同一资源,但需限制在同一时刻访问此资源的最大线程数目。在用CreateSemaphore()创建信号量时应要同时指出允许的最大资源计数和当前可用资源计数。一般将当前可用资源计数设为最大资源计数,每增一个线程对共享资源的访问,当前可用资源计数就减1,只要当前可用资源计数大于0的,就可发出信号量信号。但当前可用计数减小到0时则说明

9、当前占用资源的线程数已达到了所允许的最大数目,不能在允许其他线程的进入,这时的信号量信号将无法发出。线程在处理完共享资源后,应在离开的同时通过ReleaseSemaphore()函数将当前可用资源计数加1。在任何时候当前可用资源计数决不能大于最大资源计数。使用信号量内核对象进行线程同步主要会用到OpenSemaphore()、ReleaseSemaphore()、 CreateSemaphore()、WaitForMultipleObjects()和WaitForSingleObject()等函数。其中,CreateSemaphore()是用来创建一个信号量内核对象,其函数原型为:HANDLE

10、 CreateSemaphore(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, / 安全属性指针LONG lInitialCount, / 初始计数LONG lMaximumCount, / 最大计数LPCTSTR lpName / 对象名指针);参数lMaximumCount是一个有符号32位值,定义了允许的最大资源计数,最大取值不超过4294967295。lpName参数可为创建的信号量定义一个名字,由于其创建的是一个内核对象,所以在其他进程中可通过该名字而得到此信号量。OpenSemaphore()函数即可用来根据信号量名打开在其他进程中创建的

11、信号量,函数原型如下:HANDLE OpenSemaphore(DWORD dwDesiredAccess, / 访问标志BOOL bInheritHandle, / 继承标志LPCTSTR lpName / 信号量名);在线程离开对共享资源的处理时,一定要通过ReleaseSemaphore()来增加当前可用资源计数。否则将会导致当前正在处理共享资源的实际线程数并不能达到要限制的数值,而其他线程却因为当前可用资源计数为0但仍无法进入的情况。ReleaseSemaphore()的函数原型为:BOOL ReleaseSemaphore(HANDLE hSemaphore, / 信号量句柄LONG

12、 lReleaseCount, / 计数递增数量LPLONG lpPreviousCount / 先前计数);互斥是用途广泛的内核对象。能保证多个线程对同一共享资源的互斥访问。只有拥有互斥对象的线程才具有访问资源的权限,由于互斥对象只有一个,所以就决定了无论在什么情况下,这共享资源都不会同时被多个线程所访问。当前占据资源的线程在任务处理完后应将拥有的互斥对象交出,便于其他线程在获得后得以访问资源。互斥对象在操作系统中拥有特殊代码,并由操作系统来管理,操作系统甚至还允许它进行一些其他内核对象不能进行的非常规操作。为了便于理解,可参照互斥内核用互斥内核对象来保持线程同步可能用到的函数有OpenMu

13、tex()、ReleaseMutex()、CreateMutex()、WaitForSingleObject()和WaitForMultipleObjects()等。在使用互斥对象前,首先要通过CreateMutex()或OpenMutex()创建或打开一个互斥对象。CreateMutex()函数原型为:/ 互斥对象HANDLE hMutex = NULL;har g_cArray10;UINT ThreadProc18(LPVOID pParam)/ 等待互斥对象通知WaitForSingleObject(hMutex, INFINITE);/ 对共享资源进行写入操作for (int i =

14、 0; i < 10; i+)g_cArrayi = 'a'Sleep(1);/ 释放互斥对象ReleaseMutex(hMutex);return 0;UINT ThreadProc19(LPVOID pParam)/ 等待互斥对象通知WaitForSingleObject(hMutex, INFINITE);/ 对共享资源进行写入操作for (int i = 0; i < 10; i+)g_cArray10 - i - 1 = 'b'Sleep(1);/ 释放互斥对象ReleaseMutex(hMutex);return 0;void CSamp

15、le08View:OnMutex() / 创建互斥对象hMutex = CreateMutex(NULL, FALSE, NULL);/ 启动线程AfxBeginThread(ThreadProc18, NULL);AfxBeginThread(ThreadProc19, NULL);/ 等待计算完毕Sleep(300);/ 报告计算结果CString sResult = CString(g_cArray);AfxMessageBox(sResult);/ MFC互斥类对象CMutex g_clsMutex(FALSE, NULL);UINT ThreadProc27(LPVOID pPara

16、m)/ 等待互斥对象通知g_clsMutex.Lock();/ 对共享资源进行写入操作for (int i = 0; i < 10; i+)g_cArrayi = 'a'Sleep(1);/ 释放互斥对象g_clsMutex.Unlock();return 0;UINT ThreadProc28(LPVOID pParam)/ 等待互斥对象通知g_clsMutex.Lock();/ 对共享资源进行写入操作for (int i = 0; i < 10; i+)g_cArray10 - i - 1 = 'b'Sleep(1);/ 释放互斥对象g_clsMutex.Unlock();return 0;void CSample08View:OnMutexMfc()/ 启动线程AfxBeginThread(ThreadProc27, NULL);AfxBeginThread(ThreadProc28, NULL);/ 等待计算完毕Sleep(300);/ 报告计算结果CString sResult =

温馨提示

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

评论

0/150

提交评论