北理工操作系统实验二读者写者问题

  • 格式:doc
  • 大小:264.50 KB
  • 文档页数:13

--

-

- - 优质资料

本科实验报告

实验名称:操作系统原理实验(读者写者问题)

课程名称: 操作系统原理 实验时间: 2015.10.30

任课教师: 王耀威 实验地点: 10#102

实验教师: 苏京霞

实验类型: 原理验证

□综合设计

□自主创新 学生XX: 孙嘉明

学号/班级: 1120121474/05611202 组号:

学院: 信息与电子学院 同组搭档:

专业: 信息对抗技术 成绩:

--

-

- - 优质资料

实验二:读者写者问题

一、实验目的

1. 通过编写和调试程序以加深对进程、线程管理方案的理解;

2. 熟悉Windows多线程程序设计方法;

二、实验要求

在Windows环境下,创建一个控制台进程,此进程包含n个线程。用这n个线程来表示n个读者或写者。每个线程按相应测试数据文件(后面介绍)的要求进行读写操作。用信号量机制分别实现读者优先和写者优先问题。

读者-写者问题的读写操作限制(包括读者优先和写者优先)

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

2) 读-写互斥:不能同时有一个线程在读,而另一个线程在写。

3) 读-读允许:可以有一个或多个读者在读。

读者优先的附加限制:如果读者申请进行读操作时已有另一个读者正在进行读操作,则该读者可直接开始读操作。

运行结果显示要求:要求在每个线程创建、发出读写申请、开始读写操作和结束读写操作时分别显示一行提示信息,以确定所有处理都遵守相应的读写操作限制。

测试数据文件包括 n行测试数据,分别描述创建的n个线程是读者还是写者,以及读写操作的开始时间和持续时间。每行测试数据包括四个字段,每个字段间用空格分隔。第1个字段为正整数,表示线程的序号。第2个字段表示线程的角色,R表示读者,W表示写者。第3个字段为一个正数,表示读写开始时间:线程创建后,延迟相应时间(单位为秒)后发出对共享资源的读写申请。第4个字段为一个正数,表示读写操作的延迟时间。当线程读写申请成功后,开始对共享资源进行读写操作,该操作持续相应时间后结束,释放该资源。

下面是一个测试数据文件的例子(在记事本手工录入数据):

1 R 3 5

2 W 4 5

3 R 5 2 --

-

- - 优质资料 4 R 6 5

5 W 5.1 3

三、实验环境

硬件设备:个人计算机。

系统软件:windows操作系统,Visual C++6.0编译环境。

四、实验原理

读者写者问题,可以这样的描述,有一群写者和一群读者,写者在写同一本书,读者也在读这本书,多个读者可以同时读这本书,但是,只能有一个写者在写书,并且,读者比写者优先,也就是说,读者和写者同时提出请求时,读者优先。当读者提出请求时需要有一个互斥操作,另外,需要有一个信号量S来当前是否可操作。

信号量机制是支持多道程序的并发操作系统设计中解决资源共享时进程间的同步与互斥的重要机制,而读者写者则是这一机制的一个经典X例。

在程序文件根目录下创建一个thread.dat文件,存放读者写者信息,完成读者优先和写者优先的过程。

五、实验结果

程序界面:

使用的测试文件如下:

1 R 3 5

2 W 4 5

3 R 5 2

4 R 6 5

5 W 5.1 3

读者优先结果: --

-

- - 优质资料

写者优先结果:

--

-

- - 优质资料 六、程序代码

# include "windows.h"

# include

# include

# include

# include

# include

# include

# 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( "读者线程 <%d> 发送读文件请求.\n" , m_serial) ;

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

wait_for_mutex = WaitForSingleObject (h_Mutex, -1) ;

// 读者数目增加

readcount ++;

if (readcount == 1)

{

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

EnterCriticalSection(&RP_Write) ;

}

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

// 读文件

printf( "读者线程 <%d> 开始读文件.\n" , m_serial) ;

Sleep(m_persist) ;

// 退出线程

printf("读者线程 <%d> 读文件结束.\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("写者线程 <%d> 发送写文件请求.\n" , m_serial) ;

// 等待资源

EnterCriticalSection(&RP_Write);

// 写文件

printf( "写者线程 <%d> 开始写文件.\n" , m_serial) ;

Sleep(m_persist) ;

// 退出线程

printf("写者线程 <%d> 写文件结束.\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