分享
 
 
 

操作系统内核实验之 读者-写者实现

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

操作系统内核实验之 读者-写者实现

第一部分:说明

读者-写者问题经典的线程同步问题的一个模型,于是我制作本文,希望对学习操作系统实现的有所帮助!更希望和广大编程爱好者交朋友!至于读者-写者问题我在这也不详细的叙述了,既然您看到这个文档,我想你应该是理解了读者写者问题的了,所以我直接从代码入手,同时有简单的说明。如果你有什么地方看不懂,可以以以下的方式联系我:

■■■,E-mail:■■ QQ:■■■■ MSN:■■■■■■(推荐)

我的主页:http://www.■r■.com

特别说明:本问文档的实现技术是:

《windows内核实验教程》 机械工业出版社ISBN:7-111-10880-9/TP.2600

其中的版权也归原书所有!我希望见到本文档的人可以保证原书的版权!我只是对其中的部分进行了整理!

特别提示:

如果为了测试您对操作系统理论水平和设计,那么希望你先不要看本文档!自己独立的试着设计!

第二部分:实现

操作系统实验之 读者-写者实现代码说明文档

/////////////////////////////////

读者-写者的读写限制(包括读者优先和写者优先)

1)写-写互斥,即不能有两个写者同时进行写操作

2)读-写互斥,即不能同时有一个读者在读,同时却有一个写者在写

3)读读允许,即可以有2个以上的读者同时读

读者优先的限制:

如果一个读者申请读操作时,已经有一个读者在读,则该读者可以直接读

写者优先的限制:

如果一个读者申请读操作时,有写者在等待访问共享资源时,则该读者要等到没有写者处于等的状态时才能开始读操作

/////////////////////////////////

测试数据的格式

在文件 thread.dat 中,

1 r 3 5

2 w 4 5

....

其中第一个代表线程的ID,第二个字段代表是读操作还是写操作,第三个字段代表操作的开始时间,第4个字段是持续时间。

/////////////////////////////////

分析:

将所有的读者和所有的写者分别放进两个等待队列中,当读允许时就让读者队列释放一个或多个读者,当写允许时,释放第一个写者操作。

读者优先:

如果没有写者正在操作,则读者不需要等待,用一个整型变量readcount记录当前的读者数目,用于确定是否释放写者线程,(当readcout=0 时,说明所有的读者都已经读完,释放一个写者线程),每个 读者开始读之前都要修改readcount,为了互斥的实现对readcount 的修改,需要一个互斥对象Mutex来实现互斥。

另外,为了实现写-写互斥,需要一个临界区对象 write,当写者发出写的请求时,必须先得到临界区对象的所有权。通过这种方法,可以实现读写互斥,当readcount=1 时,(即第一个读者的到来时,),读者线程也必须申请临界区对象的所有权.

当读者拥有临界区的所有权,写者都阻塞在临界区对象write上。当写者拥有临界区对象所有权时,第一个判断完readcount==1 后,其余的读者由于等待对readcount的判断,阻塞在Mutex上!

写者优先:

写者优先和读者优先有相同之处,不同的地方在:一旦有一个写者到来时,应该尽快让写者进行写,如果有一个写者在等待,则新到的读者操作不能读操作,为此添加一个整型变量writecount,记录写者的数目,当writecount=0时才可以释放读者进行读操作!

为了实现对全局变量writecount的互斥访问,设置了一个互斥对象Mutex3。

为了实现写者优先,设置一个临界区对象read,当有写者在写或等待时,读者必须阻塞在临界区对象read上。

读者除了要一个全局变量readcount实现操作上的互斥外,还需要一个互斥对象对阻塞在read这一个过程实现互斥,这两个互斥对象分别为mutex1和mutex2。

//////////////////////////////////////

所用的API: 参数略(MSDN查看)//代码中有部分没有使用,但是可以在其他地方自己设计程序的时候使用。

1.CreateThread();

2.ExitThread();

3.Sleep();

4.CreateMutex();

5.ReleaseMutex();

6.WaitForSingleObject();

7.WaitForMutipleObjects();

8.CreateSemapore();

9.ReleaseSemapore();

10.InitializeCriticalSection();

11.EnterCriticalSection();

12.LeaveCriticalSection();

///////////////////////////////////

原代码文件名:

1.ReaderAndWriter.CPP // 具体的实现

2.thread.dat //辅助的文件,但是必不可以少。

第三部分:代码

一.ReaderAndWriter.CPP文件的具体内容:

// 来自:windows 内核实验教程

// 机械工业出版社

// ISBN:7-111-10880-9/TP.2600

//制作者:yuhejun@126.com

// For more information:www.surstar.com

// 2005.11.9

// beijing changping

// Debug Vision

// Description:这是一个关于操作系统内核实验的一段程序,读者和写者的问题的模拟实现.

// 开发环境:WINXP +VC6 Console Application

#include "windows.h"

#include <conio.h>

#include <stdlib.h>

#include <fstream.h>

#include <io.h>

#include <string.h>

#include <stdio.h>

#define READER 'R' //读者

#define WRITER 'W' //写者

#define INTE_PER_SEC 1000 //每秒时钟中断的数目

#define MAX_THREAD_NUM 64 //最大线程数

#define MAX_FILE_NUM 32 //最大文件数目数

#define MAX_STR_LEN 32 //字符串的长度

int readcount=0; //读者数目

int writecount=0; //写者数目

CRITICAL_SECTION RP_Write; //临界资源

CRITICAL_SECTION cs_Write;

CRITICAL_SECTION cs_Read;

struct ThreadInfo

{

int serial; //线程序号

char entity; //线程类别(判断是读者还是写者线程)

double delay; //线程延迟时间

double persist; //线程读写操作时间

};

///////////////////////////////////////////////////////////////////////////

// 读者优先---读者线程

//P:读者线程信息

void RP_ReaderThread(void *p)

{

//互斥变量

HANDLE h_Mutex;

h_Mutex=OpenMutex(MUTEX_ALL_ACCESS,FALSE,"mutex_for_readcount");

DWORD wait_for_mutex; //等待互斥变量所有权

DWORD m_delay; //延迟时间

DWORD m_persist; //读文件持续时间

int m_serial; //线程序号

// 从参数中获得信息

m_serial=((ThreadInfo*)(p))->serial ;

m_delay=(DWORD)(((ThreadInfo*)(p))->delay *INTE_PER_SEC);

m_persist=(DWORD)(((ThreadInfo*)(p))->persist *INTE_PER_SEC);

Sleep(m_delay); //延迟等待

printf("Reader thread %d sents the reading require.\n",m_serial);

//等待互斥信号,保证对ReadCount 的访问,修改互斥

wait_for_mutex=WaitForSingleObject(h_Mutex,-1);

//读者数目增加

readcount++;

if(readcount==1)

{

//第一个读者,等待资源

EnterCriticalSection(&RP_Write);

}

ReleaseMutex(h_Mutex); //释放互斥信号

//读文件

printf("Reader thread %d begins to read file.\n",m_serial);

Sleep(m_persist);

//退出线程

printf("Reader thread %d finished reading file.\n",m_serial);

//等待互斥信号,保证对ReadCount的访问,修改互斥

wait_for_mutex=WaitForSingleObject(h_Mutex,-1);

//读者数目减少

readcount--;

if(readcount==0)

{

//如果所有的读者读完,唤醒写者

LeaveCriticalSection(&RP_Write);

}

ReleaseMutex(h_Mutex); //释放互斥信号

}

//////////////////////////////////////////////////////////////

//P:写者线程信息

void RP_WriterThread(void *p)

{

DWORD m_delay; //延迟时间

DWORD m_persist; //写文件持续时间

int m_serial; //线程序号

// 从参数中获得信息

m_serial=((ThreadInfo*)(p))->serial ;

m_delay=(DWORD)(((ThreadInfo*)(p))->delay *INTE_PER_SEC);

m_persist=(DWORD)(((ThreadInfo*)(p))->persist *INTE_PER_SEC);

Sleep(m_delay);

printf("Write thread %d sents the writing require.\n",m_serial);

//等待资源

EnterCriticalSection(&RP_Write);

//写文件

printf("Writer thread %d begins to write to the file.\n",m_serial);

Sleep(m_persist);

//退出线程

printf("Write thread %d finished writing to the file.\n",m_serial);

//释放资源

LeaveCriticalSection(&RP_Write);

}

//////////////////////////////////////////////////////////////

//读者优先处理函数

//file:文件名

void ReaderPriority(char *file)

{

DWORD n_thread=0; //线程数目

DWORD thread_ID; //线程ID

DWORD wait_for_all; //等待所有线程结束

//互斥对象

HANDLE h_Mutex;

h_Mutex=CreateMutex(NULL,FALSE,"mutex_for_readcount");

//线程对象的数组

HANDLE h_Thread[MAX_THREAD_NUM];

ThreadInfo thread_info[MAX_THREAD_NUM];

readcount=0; //初始化readcount

InitializeCriticalSection(&RP_Write); //初始化临界区

ifstream inFile;

inFile.open (file);

printf("Reader Priority:\n\n");

while(inFile)

{

//读入每一个读者,写者的信息

inFile>>thread_info[n_thread].serial;

inFile>>thread_info[n_thread].entity;

inFile>>thread_info[n_thread].delay;

inFile>>thread_info[n_thread++].persist;

inFile.get();

}

for(int i=0;i<(int)(n_thread);i++)

{

if(thread_info[i].entity==READER||thread_info[i].entity =='r')

{

//创建读者进程

h_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(RP_ReaderThread),&thread_info[i],0,&thread_ID);

}

else

{

//创建写线程

h_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(RP_WriterThread),&thread_info[i],0,&thread_ID);

}

}

//等待所有的线程结束

wait_for_all=WaitForMultipleObjects(n_thread,h_Thread,TRUE,-1);

printf("All reader and writer have finished operating.\n");

}

////////////////////////////////////////////////////////

//写者优先---读者线程

//P:读者线程信息

void WP_ReaderThread(void *p)

{

//互斥变量

HANDLE h_Mutex1;

h_Mutex1=OpenMutex(MUTEX_ALL_ACCESS,FALSE,"mutex1");

HANDLE h_Mutex2;

h_Mutex2=OpenMutex(MUTEX_ALL_ACCESS,FALSE,"mutex2");

DWORD wait_for_mutex1; //等待互斥变量所有权

DWORD wait_for_mutex2;

DWORD m_delay; //延迟时间

DWORD m_persist; //读文件持续时间

int m_serial; //线程的序号

//从参数中得到信息

m_serial=((ThreadInfo*)(p))->serial ;

m_delay=(DWORD)(((ThreadInfo*)(p))->delay *INTE_PER_SEC);

m_persist=(DWORD)(((ThreadInfo*)(p))->persist *INTE_PER_SEC);

Sleep(m_delay); //延迟等待

printf("Reader thread %d sents the reading require.\n",m_serial);

wait_for_mutex1=WaitForSingleObject(h_Mutex1,-1);

//读者进去临界区

EnterCriticalSection(&cs_Read);

//阻塞互斥对象Mutex2,保证对readCount的访问和修改互斥

wait_for_mutex2=WaitForSingleObject(h_Mutex2,-1);

//修改读者的数目

readcount++;

if(readcount==1)

{

// 如果是第1个读者,等待写者写完

EnterCriticalSection(&cs_Write);

}

ReleaseMutex(h_Mutex2);// 释放互斥信号 Mutex2

//让其他读者进去临界区

LeaveCriticalSection(&cs_Read);

ReleaseMutex(h_Mutex1);

//读文件

printf("Reader thread %d begins to read file.\n",m_serial);

Sleep(m_persist);

//退出线程

printf("Reader thread %d finished reading file.\n",m_serial);

//阻塞互斥对象Mutex2,保证对readcount的访问,修改互斥

wait_for_mutex2=WaitForSingleObject(h_Mutex2,-1);

readcount--;

if(readcount==0)

{

//最后一个读者,唤醒写者

LeaveCriticalSection(&cs_Write);

}

ReleaseMutex(h_Mutex2); //释放互斥信号

}

///////////////////////////////////////////

//写者优先---写者线程

//P:写者线程信息

void WP_WriterThread(void *p)

{

DWORD wait_for_mutex3; //互斥变量

DWORD m_delay; //延迟时间

DWORD m_persist; //读文件持续时间

int m_serial; //线程序号

HANDLE h_Mutex3;

h_Mutex3=OpenMutex(MUTEX_ALL_ACCESS,FALSE,"mutex3");

//从参数中获得信息

m_serial=((ThreadInfo*)(p))->serial ;

m_delay=(DWORD)(((ThreadInfo*)(p))->delay *INTE_PER_SEC);

m_persist=(DWORD)(((ThreadInfo*)(p))->persist *INTE_PER_SEC);

Sleep(m_delay); //延迟等待

printf("Writer thread %d sents the reading require.\n",m_serial);

wait_for_mutex3=WaitForSingleObject(h_Mutex3,-1);

writecount++; //修改写者数目

if(writecount==1)

{

EnterCriticalSection(&cs_Read);

}

ReleaseMutex(h_Mutex3);

EnterCriticalSection(&cs_Write);

printf("Writer thread %d begins to write to the file.\n",m_serial);

Sleep(m_persist);

printf("Writer thread %d finished writing to the file.\n",m_serial);

LeaveCriticalSection(&cs_Write);

wait_for_mutex3=WaitForSingleObject(h_Mutex3,-1);

writecount--;

if(writecount==0)

{

LeaveCriticalSection(&cs_Read);

}

ReleaseMutex(h_Mutex3);

}

/////////////////////////////////////////////

//写者优先处理函数

// file:文件名

void WriterPriority(char * file)

{

DWORD n_thread=0;

DWORD thread_ID;

DWORD wait_for_all;

HANDLE h_Mutex1;

h_Mutex1=CreateMutex(NULL,FALSE,"mutex1");

HANDLE h_Mutex2;

h_Mutex2=CreateMutex(NULL,FALSE,"mutex2");

HANDLE h_Mutex3;

h_Mutex3=CreateMutex(NULL,FALSE,"mutex3");

HANDLE h_Thread[MAX_THREAD_NUM];

ThreadInfo thread_info[MAX_THREAD_NUM];

readcount=0;

writecount=0;

InitializeCriticalSection(&cs_Write);

InitializeCriticalSection(&cs_Read);

ifstream inFile;

inFile.open (file);

printf("Writer priority:\n\n");

while(inFile)

{

inFile>>thread_info[n_thread].serial;

inFile>>thread_info[n_thread].entity;

inFile>>thread_info[n_thread].delay;

inFile>>thread_info[n_thread++].persist;

inFile.get();

}

for(int i=0;i<(int)(n_thread);i++)

{

if(thread_info[i].entity==READER||thread_info[i].entity =='r')

{

//创建读者进程

h_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(WP_ReaderThread),&thread_info[i],0,&thread_ID);

}

else

{

//创建写线程

h_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(WP_WriterThread),&thread_info[i],0,&thread_ID);

}

}

//等待所有的线程结束

wait_for_all=WaitForMultipleObjects(n_thread,h_Thread,TRUE,-1);

printf("All reader and writer have finished operating.\n");

}

/////////////////////////////////////////////////////

//主函数

int main(int argc,char *argv[])

{

char ch;

while(true)

{

printf("*************************************\n");

printf(" 1.Reader Priority\n");

printf(" 2.Writer Priority\n");

printf(" 3.Exit to Windows\n");

printf("*************************************\n");

printf("Enter your choice(1,2,3): ");

do{

ch=(char)_getch();

}while(ch!='1'&&ch!='2'&&ch!='3');

system("cls");

if(ch=='3')

return 0;

else if(ch=='1')

ReaderPriority("thread.dat");

else

WriterPriority("thread.dat");

printf("\nPress Any Key to Coutinue:");

_getch();

system("cls");

}

return 0;

}

二.thread.dat 的内容

1 r 3 5

2 w 4 5

3 r 5 2

4 r 6 5

5 w 5.1 3

第四部分:免责声明

1. 希望大家保持本文档的完整性。

2. 如果你要使用其中的代码,请著名:版权归原书所有。

3. 请不要想其他的人随便传递此文档,本人不担当任何后果。

二〇〇四年十一月十四日星期日

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有