Visual Studio 2008

参考(http://blog.csdn.net/melody_1208/article/details/2027507

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

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

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

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

3)读-读互斥,即可以有一个或多个读者在读。

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

写者优先的附加限制:如果一个读者申请进行读操作时已有另一个写者在等待访问共享资源,则该读者必须等到没有写者出于等待状态后才能开始读操作。

测试文件格式说明,下面是一个测试数据文件的例子:

1 R 3 5
2 W 4 5
3 R 5 2
4 R 6 5
5 W 5.1 3
6 R 15 4
7 R 15 4

 

View Code
#include <Windows.h>
#include <conio.h>
#include <cstdlib>
#include <stdio.h>
#include <fstream>
using namespace std;

#define READER 'R'
#define WRITER 'W'
#define INTE_PER_SEC 1000 //interrupt number per second
#define MAX_THREAD_NUM 64 //max thread number

int readCount = 0;
int writeCount = 0;

CRITICAL_SECTION RP_Writer; //Critical Section
CRITICAL_SECTION cs_Writer;
CRITICAL_SECTION cs_Read;

struct ThreadInfo
{
int serial; //the serial number of the thread
char entity; //type of thread(reader or writer)
double delay; //delay of thread
double persist; //time of thread's read and write operation
};

void RP_ReaderThread(void *p);
void RP_WriterThread(void *p);
void ReaderPriority(char *file);

void WP_ReaderThread(void *p);
void WP_WriterThread(void *p);
void WriterPriority(char *file);

int main()
{
char ch;
while (true)
{
printf("*************************************************\n");
printf(" 1: Read Priority\n");
printf(" 2: Writer Priority \n");
printf(" 3: Exit\n");
printf("*************************************************\n");
printf("Enter your choice(1, 2 or 3)\n");

//input is incorrect
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 Continue:\n");
_getch();
//system("cls");
}
return 0;
}

void RP_ReaderThread(void *p)
{
//execlusive object
HANDLE h_Mutex;
h_Mutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, "mutex_for_readCount");

DWORD wait_for_mutex; //wait for the execlusive object
DWORD m_delay; //delay time
DWORD m_persist; //the time of read file operation
int m_serial; //serical number of the thread

//get the information from the parameter
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); //wait for a little while

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

wait_for_mutex = WaitForSingleObject(h_Mutex, -1);

readCount++;
if (readCount == 1)
{
//the first reader, wait for resource
EnterCriticalSection(&RP_Writer);
}
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);
wait_for_mutex = WaitForSingleObject(h_Mutex, -1);
readCount--;
if (readCount == 0)
{
//if all readers finished their operation, wake up the writer
LeaveCriticalSection(&RP_Writer);
printf("Reader thread %d leave the critical section\n", m_serial);
}
ReleaseMutex(h_Mutex);
}

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("Writer thread %d sents the writing require \n", m_serial);
EnterCriticalSection(&RP_Writer);

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

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

LeaveCriticalSection(&RP_Writer);
}

void ReaderPriority(char *file)
{
DWORD n_thread = 0; //number of threads
DWORD thread_ID; //thread ID
DWORD wait_for_all; //wait for all threads

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; //initialize readcount
InitializeCriticalSection(&RP_Writer);
fstream inFile;
inFile.open(file);
printf("Read Priority \n\n");
while(inFile)
{
//Read every writer, reader's information
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')
{
//create reader thread
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 thread to terminate
wait_for_all = WaitForMultipleObjects(n_thread, h_Thread, TRUE, -1);
printf("All reader and writer have finished operating \n");
}

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; //latency time
DWORD m_persist; //the time it used for reading the file
int m_serial; //the serial number of the thread

//get information from the parameter
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 sends the reading require \n", m_serial);
wait_for_mutex1 = WaitForSingleObject(h_Mutex1, -1);

//enter the reader's critical section
EnterCriticalSection(&cs_Read);

//block execlusive object mutex2, ensure the access, modify to readcount is execlusive
wait_for_mutex2 = WaitForSingleObject(h_Mutex2, -1);
readCount++;
if (readCount == 1)
{
//if it is the first reader, wait for the writer finish
EnterCriticalSection(&cs_Writer);
}
ReleaseMutex(h_Mutex2);

//let other reader enter the critical section
LeaveCriticalSection(&cs_Read);
ReleaseMutex(h_Mutex1);

//read file
printf("Reader thread %d begins to read file \n", m_serial);
//block exevlusive object mutex2, ensure the access, modify to readcount is execlusive
wait_for_mutex2 = WaitForSingleObject(h_Mutex2, -1);
readCount--;
if (readCount == 0)
{
//the last reader, wake up writer
LeaveCriticalSection(&cs_Writer);
}
ReleaseMutex(h_Mutex2);
}

void WP_WriterThread(void *p)
{
DWORD m_delay;
DWORD m_persist;
int m_serial;
DWORD wait_for_mutex3;
HANDLE h_Mutex3;
h_Mutex3 = OpenMutex(MUTEX_ALL_ACCESS, FALSE,"mutex3");

//get information from the parameter
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 sends the writing require\n", m_serial);

wait_for_mutex3 = WaitForSingleObject(h_Mutex3, -1);
writeCount++;
if (writeCount == 1)
{
//the first writer, wait for the read finsih
EnterCriticalSection(&cs_Read);
}
ReleaseMutex(h_Mutex3);

//enter the writer critical section
EnterCriticalSection(&cs_Writer);

//write the file
printf("Write thread %d begins to write to the file \n", m_serial);
Sleep(m_persist);

//exit the thread
printf("Write thread %d finishing writing to the file\n", m_serial);
//leave the critical section
LeaveCriticalSection(&cs_Writer);

wait_for_mutex3 = WaitForSingleObject(h_Mutex3, -1);
writeCount--;
if (writeCount == 0)
{
//writer finished, reader can read
LeaveCriticalSection(&cs_Read);
}
ReleaseMutex(h_Mutex3);
}

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");

//thread object
HANDLE h_Thread[MAX_THREAD_NUM];
ThreadInfo thread_info[MAX_THREAD_NUM];

readCount = 0;
writeCount = 0;
InitializeCriticalSection(&cs_Writer);
InitializeCriticalSection(&cs_Read);
fstream inFile;
inFile.open(file);
printf("Write 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')
{
//create reader thread
h_Thread[i] = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE)(WP_ReaderThread),
&thread_info[i],
0,
&thread_ID);
}
else
{
//create writer thread
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");
}



posted on 2012-04-03 13:27  Lee_Alvin  阅读(656)  评论(0编辑  收藏  举报