读者写者实验

创建一个控制台进程。此进程包含n个线程。用这n个线程来表示n个读者或写者。每个线程按相应测试数据文件(后面有介绍)的要求进行读写操作。用信号量机制分别实现读者优先和写者优先的读者-写者问题。
    读者-写者问题的读写操作限制(包括读者优先和写者优先):
    1)写-写互斥,即不能有两个写者同时进行写操作。
    2)读-写互斥,即不能同时有一个线程在读,而另一个线程在写。
    3)读-读允许,即可以有一个或多个读者在读。
    读者优先的附加限制:如果一个读者申请进行读操作时已有另一个读者正在进行读操作,则该读者可直接开始读操作。
    写者优先的附加限制:如果一个读者申请进行读操作时已有另一写者在等待访问共享资源,则该读者必须等到没有写者处于等待状态后才能开始读操作。
运行结果显示要求:要求在每个线程创建、发出读写操作申请、开始读写操作和结束读写操作时分别显示一行提示信息,以确定所有处理都遵守相应的读写操作限制。

可以将所有读者和所有写者分别存于一个读者等待队列和一个写者等待队列中,每当读允许时,.就从读者队列中释放一个或多个读者线程进行读操作;每当写允许时,就从写者队列中释放一个写者进行写操作。

#include <stdio.h>
#include <windows.h>
#include <iostream>
using namespace std;
CRITICAL_SECTION mutex;
CRITICAL_SECTION mutexr;
int ReadCount;
int wnum[100][3];
int rnum[100][3];
int Numr = 0;
int Numw = 0;
DWORD WINAPI Reader(LPVOID pArg)
{
	    Sleep(rnum[(int)pArg][1]*1000);
		printf("\n读者%d等待读......", rnum[(int)pArg][0]);
		EnterCriticalSection(&mutexr);
		if (ReadCount == 0)
			EnterCriticalSection(&mutex);
		ReadCount++;
		LeaveCriticalSection(&mutexr);
		printf("\n读者%d正在读......", rnum[(int)pArg][0]);
		Sleep(rnum[(int)pArg][2]*1000);
		printf("\n读者%d结束读......", rnum[(int)pArg][0]);
		EnterCriticalSection(&mutexr);
		ReadCount--;
		if (ReadCount == 0)
			LeaveCriticalSection(&mutex);
		LeaveCriticalSection(&mutexr);
	return 0;
}

DWORD WINAPI Writer(LPVOID pArg)
{
	Sleep(wnum[(int)pArg][1] * 1000);
	printf("\n\t\t\t写者%d等待写......", wnum[(int)pArg][0]);
	EnterCriticalSection(&mutex);
	printf("\n\t\t\t写者%d正在写......", wnum[(int)pArg][0]);
	Sleep(wnum[(int)pArg][2] * 1000);
	printf("\n\t\t\t写者%d结束写......", wnum[(int)pArg][0]);
	LeaveCriticalSection(&mutex);
	return 0;
}
int main()
{
	char ch;
	FILE *p;
	int tmp=0;
	p = fopen("test.txt", "r");
	fscanf(p, "%d", &tmp); 
	while (tmp != EOF)
	{
		ch = getc(p);
		while (!(ch == 'W' || ch == 'R'))
		{
			if (ch == EOF)
				goto T;
			ch = getc(p);
		}
		if (ch == 'W')
		{
			wnum[Numw][0] = tmp;
			fscanf(p, "%d", &wnum[Numw][1]);
			fscanf(p, "%d", &wnum[Numw][2]);
			Numw++;
		}
		else if (ch == 'R')
		{
			rnum[Numr][0] = tmp;
			fscanf(p, "%d", &rnum[Numr][1]);
			fscanf(p, "%d", &rnum[Numr][2]);
			Numr++;
		}
		fscanf(p, "%d", &tmp);
	}
T:;
	/*for (int i = 0; i < Numr; i++)
	{
		printf("%d", rnum[i][0]);
		printf("%d", rnum[i][1]);
		printf("%d", rnum[i][2]);
	}*/


	ReadCount = 0;

	InitializeCriticalSection(&mutex);

	InitializeCriticalSection(&mutexr);

	HANDLE WThread[20];
	HANDLE RThread[20];

	for (int i = 0; i<Numr; i++)
		RThread[i] = CreateThread(NULL, 0, Reader, (LPVOID)i, 0, NULL);//建立读线程
	for (int i = 0; i<Numw; i++)
		WThread[i] = CreateThread(NULL, 0, Writer, (LPVOID)i, 0, NULL);//建立写线程

	WaitForMultipleObjects(Numr, RThread, TRUE, INFINITE);
	WaitForMultipleObjects(Numw, WThread, TRUE, INFINITE);


	system("pause");
	return 0;
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Windows2000环境下,创建一个控制台进程,此进程包含n个线程。用这n个线程来表示n个读者写者。每个线程按相应测试数据文件(后面有介绍)的要求进行读写操作。用信号量机制分别实现读者优先和写者优先的读者-写者问题。 读者-写者问题的读写操作限制(包括读者优先和写者优先): 1)写-写互斥,即不能有两个写者同时进行写操作。 2)读-写互斥,即不能同时有一个线程在读,而另一个线程在写。, 3)读-读允许,即可以有一个或多个读者在读。 读者优先的附加限制:如果一个读者申请进行读操作时已有另一个读者正在进行读操作,则该读者可直接开始读操作。 写者优先的附加限制:如果一个读者申请进行读操作时已有另一写者在等待访问共享资源,则该读者必须等到没有写者处于等待状态后才能开始读操作。 运行结果显示要求:要求在每个线程创建、发出读写操作申请、开始读写操作和结束读写操作时分别显示一行提示信息,以确定所有处理都遵守相应的读写操作限制。 2测试数据文件格式 测试数据文件包括n行测试数据,分别描述创建的n个线程读者还是写者,以及读写操作的开始时间和持续时间。每行测试数据包括四个字段,各个字段间用空格分隔。第一字段为一个正整数,表示线程序号。第二字段表示相应线程角色,R表示读者,w表示写者。第三字段为一个正数,表示读写操作的开始时间:线程创建后,延迟相应时间(单位为秒)后发出对共享资源的读写申请。第四字段为一个正数,表示读写操作的持续时间。当线程读写申请成功后,开始对共 享资源的读写操作,该操作持续相应时间后结束,并释放共享资源。 下面是一个测试数据文件的例子: 2 W 4 5 3 R 5 2 4 R 6 5 5 W 5.1 3

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值