实验要求:
有两组并发进程:读者和写者,共享一个文件F,要求:
(1)允许多个读者可同时对文件执行读操作;
(2)只允许一个写者往文件中写信息;
(3)任一写者在完成写操作之前不允许其他读者或写者工作;
(4)写者执行写操作前,应需已有的写者和读者全部退出。
(5) 要求仿真程序产生3个读者进程,两个写者进程,读写者都周期性地产生读写要求,读写操作要持续一定时间。
// C
#include "stdafx.h"
#include<semaphore.h>
#include <windows.h>
#include <conio.h>
#include <stdlib.h>
//#include <fstream.h>
#include <fstream>
#include <io.h>
#include <string.h>
#include <stdio.h>
//ReleaseSemaphore 按指定数量增加指定信号量对象的计数
#define INTE_PER_SEC 100
#define MAX_THREAD_NUM 64
#define SEM_MAX_FULL 64
#define WRITER 'W'
#define READER 'R'
using namespace std;
struct ThreadInfo
{
int serial;//序号
char entity;// 身份
double delay;//延迟
double persist;//持续时间
};//线程信息
int read_count=0;
HANDLE mutex,w;//mutex用于对计数器read_count操作的互斥信号量,w用于是否允许写的信号量
HANDLE book;
void Thread_reader(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);
while (true)
{
Sleep(m_delay);
printf("people of number%d send the Read require\n",m_serial);
WaitForSingleObject(w,INFINITE); //判断信号量是否进行占用
WaitForSingleObject(mutex,INFINITE); //判断read_count是否进行占用 并等待
printf(" thread %d Begin to Read\n",m_serial);
read_count= read_count + 1;
printf("there are %d people reading.\n",read_count);
if(read_count==1)WaitForSingleObject(book,INFINITE);//判断当前是否只有一人进行操作并等待
ReleaseSemaphore(mutex,1,NULL);
ReleaseSemaphore(w,1,NULL);
printf("there are %d people reading.\n",read_count);
Sleep(m_persist);
printf("there are %d people reading.\n",read_count);
WaitForSingleObject(mutex,INFINITE);
read_count = read_count - 1;
if (read_count == 0)
{ReleaseSemaphore(book,1,NULL);
printf("there are %d people reading.\n",read_count);}
ReleaseSemaphore(mutex,1,NULL);
}
}
void Thread_writer(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);
while (true)
{
Sleep(m_delay);
printf("people of number%d send the Write require\n",m_serial);
WaitForSingleObject(w,INFINITE);// 判断并等待读写信号量是否被占用
WaitForSingleObject(book,INFINITE);//判断并等待资源是空闲的
printf(" people of number%d Begin to Write\n",m_serial);
Sleep(m_persist);
ReleaseSemaphore(book,1,NULL);
printf(" thread %d Finish Write\n",m_serial);
//ReleaseSemaphore(book,1,NULL);
ReleaseSemaphore(w,1,NULL);
}
}
void WriterReader(char *file)
{
DWORD n_thread = 0;
DWORD thread_ID ;
HANDLE h_Thread[MAX_THREAD_NUM];
ThreadInfo thread_info[MAX_THREAD_NUM];
w=CreateSemaphore(NULL,1,1,NULL);//写者优先
mutex=CreateSemaphore(NULL,1,1,NULL);//互斥信号量
book= CreateSemaphore(NULL,1,1,NULL);//资源
ifstream inFile;
inFile.open(file);
puts("Read Data File \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;
n_thread++;
inFile.get();
}
for(int i=0;i<(int)(n_thread);i++)
{
if(thread_info[i].entity == WRITER)
h_Thread[i] = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)( Thread_writer),
&thread_info[i],0,&thread_ID);
else
{
if(thread_info[i].entity == READER)
h_Thread[i] = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)( Thread_reader),
&thread_info[i],0,&thread_ID);
else
{
puts("Bad File\n");
exit(0);
}
}
}
WaitForMultipleObjects(n_thread,h_Thread,TRUE,-1);
printf("Task is Finished!\n");
getch();
}
int main(int argc, char* argv[])
{
WriterReader("pc_data.txt");
return 0;
}