临界区(Critical Section)是一段独占对某些共享资源访问的代码,在任意时刻只允许一个线程对共享资源进行访问。如果有多个线程试图同时访问临界区,那么在有一个线程进入后其他所有试图访问此临界区的线程将被挂起,并一直持续到进入临界区的线程离开。临界区在被释放后,其他线程可以继续抢占,并以此达到用原子方式操作共享资源的目的。
临界区在使用时以CRITICAL_SECTION结构对象保护共享资源,并分别用EnterCriticalSection()和LeaveCriticalSection()函数去标识和释放一个临界区。所用到的CRITICAL_SECTION结构对象必须经过InitializeCriticalSection()的初始化后才能使用,而且必须确保所有线程中的任何试图访问此共享资源的代码都处在此临界区的保护之下。否则临界区将不会起到应有的作用,共享资源依然有被破坏的可能。
2、定义线程结构:
struct ThreadInfo
{ int Threadhao;
char ThreadClass;
double ThreadStartTime;
double ThreadRunTime;
};
此结构用来存放线程的信息,四个成员变量依次表示线程序号、线程类别、线程开始时间、线程读写持续时间。
3、互斥对象
创建互斥对象
CreateMutex(NULL,FALSE,"mutex_for_readcount");
参数含义如下:
NULL表示创建带有默认安全性的内核对象
FALSE表示该互斥对象没有被任何线程所拥有
mutex_for_readcount是为内核对象赋予名字。
释放互斥信号
ReleaseMutex(h_Mutex);
对资源具有访问权的线程不再需要访问此资源而要离开时,必须通过ReleaseMutex()函数来释放其拥有的互斥对象
4、创建读者线程
CreateThread(NULL,0,\(LPTHREAD_START_ROUTINE)(R_ReaderThread),
\&thread_info[i],0,&thread_ID);
参数含义如下:
NULL表示创建带有默认安全性的内核对象
0表示新读者线程拥有自己的堆栈,使用缺省大小:1MB。
(LPTHREAD_START_ROUTINE)(R_ReaderThread)表示新读者线程执行的线程函数的地址
&thread_info[i]表示在线程启动执行时将该参数传递给读者线程函数。
0表示读者线程创建后可以立即进行调度
&thread_ID表示CreateThread使用这个地址来存放系统分配
给新读者线程的I D
5、等待函数
WaitForMultipleObjects(n_thread,h_Thread,TRUE,-1);
等待函数可使线程自愿进入等待状态,直到一个特定的内核对象变为已通知状态为止
参数含义如下:n_thread表示线程数量。
h_Thread是指向线程对象句柄的数组的指针。
ture表示:在所有线程对象变为已通知状态之前,该函数将不允许调用线程运行
参数 -1 告诉系统,调用线程愿意永远等待下去(无限时间量),直到该进程终止运行。
三、运行结果
程序运行结果如下:
***************本程序实现读者-写者问题**************
1:读者优先
2:写者优先
3:退出
****************************************************
请选择要进行的操作:
1 (回车)
读者优先:读者线程 1 发出读请求.
读者线程 1 开始读文件.
写者线程 2 发出写请求.
读者线程 3 发出读请求.
读者线程 3 开始读文件.
写者线程 5 发出写请求.
读者线程 4 发出读请求.
读者线程 4 开始读文件.
读者线程 3 完成读文件.
读者线程 1 完成读文件.
读者线程 4 完成读文件.
写者线程 2 开始写文件.
写者线程 2 完成写文件.
写者线程 5 开始写文件.
写者线程 5 完成写文件.
所有的读者和写者线程完成操作.
是否还有继续? 1. 继续 2.退出
1 (回车)
***************本程序实现读者-写者问题**************
1:读者优先
2:写者优先
3:退出
****************************************************
请选择要进行的操作:
2 (回车)
写者优先:读者线程 1 发出读请求.
读者线程 1 开始读文件.
写者线程 2 发出写请求.
读者线程 3 发出读请求.
写者线程 5 发出写请求.
读者线程 4 发出读请求.
读者线程 1 完成读文件.
写者线程 2 开始写文件.
写者线程 2 完成写文件.
写者线程 5 开始写文件.
写者线程 5 完成写文件.
读者线程 3 开始读文件.
读者线程 4 开始读文件.
读者线程 3 完成读文件.
读者线程 4 完成读文件.
所有的读者和写者线程完成操作.是否还有继续? 1. 继续 2.退出
上一页 [1] [2] [3] [4] [5] [6] 下一页