📄 read-first.cpp
字号:
//
//*************************** 读者和写者问题 ******************************//
//
//******************************* (读者优先) *******************************//
//
//****************** 作者: happy_zh ****************************//
//
//**************************** 2004年12月 ***************************//
//
// 操作限制:
// 1)写-写互斥;
// 2)读-写互斥;
// 3)读-读允许;
// 读者优先的附加限制:如果一个读者申请进行读操作时已有另一读者正在进行读操作,
// 则该读者可直接开始读操作。
#include <windows.h>
#include <fstream.h>
#include <stdio.h>
#include <string.h>
#include <conio.h>
#define INTE_PER_SEC 1000 //秒到微秒的乘法因子.
#define MAX_THREAD_NUM 5 //本程序允许的读者和写者线程的总数.(最多线程是10个)。
struct ThreadInfo //创建线程类,记录在测试文件中指定的每一个线程的参数。
{
int serial; //线程号
char entity; //是p还是c.(char型的实体线程)。
double delay; //double型的延迟(时间)。
double runtime; //运行的时间
};
//全局变量的定义
//临界区对象的声明,用于管理缓冲区的互斥访问.
int RW_Critical = -1; //用于存放读写内容的空间
HANDLE h_Thread[MAX_THREAD_NUM]; //用于存储每个线程句柄的数组
ThreadInfo Thread_Info[MAX_THREAD_NUM]; //线程信息数组
HANDLE R_mutex; //一个写线程的互斥量
HANDLE W_mutex; //一个互斥量
double n_RThread=0; //实际的正在读的线程数目
//生产消费及辅助函数的声明
void Write(void *p);
void Read(void *p);
int main(int argc,char **argv)
{
printf("This is reader first ! \n");
//声明所需变量
DWORD wait_for_all;
ifstream inFile;
if (argc!=2) {
printf("Usage:%s <test.txt>\n",argv[0]);
return 1;
}
//打开输入文件,按照规定的格式提取线程等信息.
inFile.open(argv[1]);
//inFile.open("test.txt");
printf("New Input file is: test.txt\n");
//提取每个线程的信息到相应数据结构中
int initlnum=0;
while (inFile) {
inFile >> Thread_Info[initlnum].serial;
inFile >> Thread_Info[initlnum].entity;
inFile >> Thread_Info[initlnum].delay;
inFile >> Thread_Info[initlnum].runtime;
inFile.get();
initlnum++;
}
//回显获得的线程信息,便于确认正确性
for (int j=0;j<(int)MAX_THREAD_NUM;j++) {
int Temp_serial=Thread_Info[j].serial;
char Temp_entity=Thread_Info[j].entity;
double Temp_delay=Thread_Info[j].delay;
double Temp_runtime=Thread_Info[j].runtime;
printf(" \n thread %2d %c %f %f ",Temp_serial,Temp_entity,Temp_delay,Temp_runtime);
cout<<endl;
}
printf("\n\n");
//创建在摸迷过程中几个必要的信号量
R_mutex=CreateSemaphore(NULL,1,1,"mutex_for_Read");
W_mutex=CreateSemaphore(NULL,1,1,"mutex_for_Write");
//return 0;
//创建生产者和消费者线程
for (int i=0;i<(int)MAX_THREAD_NUM;i++) {
if (Thread_Info[i].entity=='W')
h_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(Write),&(Thread_Info[i]),0,NULL);
else
h_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(Read),&(Thread_Info[i]),0,NULL);
}
//主程序等待各个线程的动作结束
wait_for_all=WaitForMultipleObjects(MAX_THREAD_NUM,h_Thread,TRUE,-1);
printf(" \n\nAll write and read have finished their work.\n");
printf("Press any key to quit!\n");
_getch();
return 0;
}
//写进程
void Write(void *p)
{
DWORD wait_for_semaphore,m_delay,m_runtime;
int m_serial;
//获得本线程的信息
m_serial=((ThreadInfo *)(p))->serial;
m_delay=(DWORD)(((ThreadInfo *)(p))->delay*INTE_PER_SEC);
m_runtime=(DWORD)(((ThreadInfo *)(p))->runtime*INTE_PER_SEC);
Sleep(m_delay); //Sleep 可在指定的时间内挂起当前线程。
//进程开始申请资源
printf("Writer %2d requires to write .\n",m_serial);
//确认互斥信号,没有线程在写时,可以进行写操作
wait_for_semaphore = WaitForSingleObject(W_mutex,-1);
//如果申请到资源,则写入RW_Critical写入写线程的线程号
printf("Writer %2d begins to write.\n",m_serial);
Sleep(m_runtime); //必须要执行runtime这么长的时间才释放资源
RW_Critical=m_serial;
ReleaseSemaphore(W_mutex,1,NULL); //固有函数:ReleaseSemaphore 释放对互斥对象的占用,使之成为可用。
printf("Writer %2d finishes write. \n",m_serial);
}
//读者进程
void Read(void *p)
{
DWORD wait_for_semaphore,m_delay,m_runtime;
int m_serial,value;
//提取本线程的信息到本地
m_serial=((ThreadInfo *)(p))->serial;
m_delay=(DWORD)(((ThreadInfo *)(p))->delay*INTE_PER_SEC);
m_runtime=(DWORD)(((ThreadInfo *)(p))->runtime*INTE_PER_SEC);
Sleep(m_delay); //开始时间
//请求读
printf("Reader %2d requests to Read.\n",m_serial);
wait_for_semaphore = WaitForSingleObject(R_mutex,-1);
if (n_RThread == 0 )
wait_for_semaphore = WaitForSingleObject(W_mutex,-1);
printf("Reader %2d begins to read. \n",m_serial);
n_RThread++;
ReleaseSemaphore(R_mutex,1,NULL);
Sleep(m_runtime); //执行runtime这么长的时间
value = RW_Critical;
wait_for_semaphore = WaitForSingleObject(R_mutex,-1);
n_RThread--;
if (n_RThread == 0)
ReleaseSemaphore(W_mutex,1,NULL);
ReleaseSemaphore(R_mutex,1,NULL);
printf("Reader %2d finishes reading\n",m_serial);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -