读写者问题-写者优先

这是写者优先的读写者问题

/*
* 	这是一个写者优先的读写者问题
*/
# include <stdio.h>
# include <stdlib.h>
# include <time.h>
# include <sys/types.h>
# include <pthread.h>
# include <semaphore.h>
# include <string.h>
# include <unistd.h>

// 信号量
sem_t RWMutex;					// 读着写者的互斥锁,也由它控制写者优先
sem_t mutexWriteCount; 			// 控制writeCount互斥访问
sem_t mutexReadCount;			// 控制readCount互斥访问	
sem_t wrt;						// 控制写者是否可以写

// 记录读者和写者的个数
int writeCount;
int readCount;


// 线程参数
struct data {
	int id;				
	int opTime;
	int lastTime;
};

//读者
void* Reader(void* param) {
	int id = ((struct data*)param)->id;
	int lastTime = ((struct data*)param)->lastTime;
	int opTime = ((struct data*)param)->opTime;

	sleep(opTime);
	printf("第 %d 个读者线程正在{等待}读\n", id);	

	sem_wait(&RWMutex);
	sem_wait(&mutexReadCount);
	readCount++;
	if(readCount == 1)
		sem_wait(&wrt);
	sem_post(&mutexReadCount);
	sem_post(&RWMutex);

	printf("第 %d 个读者线程{开始}读\n", id);
	sleep(lastTime);
	printf("第 %d 个读者线程{结束}读\n", id);

	sem_wait(&mutexReadCount);
	readCount--;
	if(readCount == 0)
		sem_post(&wrt);
	sem_post(&mutexReadCount);

	pthread_exit(0);
}

//写者
void* Writer(void* param) {
	int id = ((struct data*)param)->id;
	int lastTime = ((struct data*)param)->lastTime;
	int opTime = ((struct data*)param)->opTime;

	sleep(opTime);
	printf("第 %d 个写者线程{等待}写\n", id);
	
	sem_wait(&mutexWriteCount);
	writeCount++;
	if(writeCount == 1){
		sem_wait(&RWMutex);
	}
	sem_post(&mutexWriteCount);
	
	sem_wait(&wrt);
	printf("第 %d 个写者线程{开始}写\n", id);
	sleep(lastTime);
	printf("第 %d 个写者线程{结束}写\n", id);
	sem_post(&wrt);

	sem_wait(&mutexWriteCount);
	writeCount--;
	if(writeCount == 0) {
		sem_post(&RWMutex);
	}
	sem_post(&mutexWriteCount);
	
	pthread_exit(0);
}

int main() {
	// 设置随机数种子
	srand((unsigned)time(NULL));

	// 线程初始化
	pthread_t tid;
	pthread_attr_t attr;
	pthread_attr_init(&attr);

	// 初始化信号量
    sem_init(&mutexWriteCount, 0, 1);
    sem_init(&mutexReadCount, 0, 1);
    sem_init(&wrt, 0, 1);
    sem_init(&RWMutex, 0, 1);

    readCount = writeCount = 0;

	int id = 0;
	while(1) {
		// 生成读者(0)或者写者(1)
		int roleID = rand() % 2;
		int opTime;		//操作时间
		int lastTime;	//持续时间

		printf("\n【NEW】来了一位 %s\n", (roleID == 0 ? "读者" : "写者"));

		// 假定操作的时间都是1s
		opTime = 1;
		lastTime = 1;

		struct data* d = (struct data*)malloc(sizeof(struct data));

		d->id = id;
		d->opTime = opTime;
		d->lastTime = lastTime;

		if(roleID == 0) {
			printf("创建第 %d 个读者线程去读\n", id);
			pthread_create(&tid, &attr, Reader, d);

		}
		else if(roleID == 1) {
			printf("创建第 %d 个写者线程去写\n", id);
			pthread_create(&tid, &attr, Writer, d);
		}

		// 每隔一段时间 随机生成一个读写者
		sleep(rand() % 2);

		++id;
	}

	sem_destroy(&mutexWriteCount);
	sem_destroy(&mutexReadCount);
	sem_destroy(&RWMutex);
	sem_destroy(&wrt);

	return 0;
}

编译命令

# compile
gcc main.c -o main -lpthread

程序输出

每隔一段时间,随机生成一个读者或写者

【NEW】来了一位 读者
创建第 0 个读者线程去读
第 0 个读者线程正在{等待}读
第 0 个读者线程{开始}读

【NEW】来了一位 读者
创建第 1 个读者线程去读
第 0 个读者线程{结束}读

【NEW】来了一位 读者
创建第 2 个读者线程去读
第 1 个读者线程正在{等待}读
第 1 个读者线程{开始}读

【NEW】来了一位 读者
创建第 3 个读者线程去读
第 2 个读者线程正在{等待}读
第 2 个读者线程{开始}读
第 1 个读者线程{结束}读
第 2 个读者线程{结束}读
第 3 个读者线程正在{等待}读
第 3 个读者线程{开始}读

【NEW】来了一位 读者
创建第 4 个读者线程去读
第 3 个读者线程{结束}读

【NEW】来了一位 读者
创建第 5 个读者线程去读
第 4 个读者线程正在{等待}读
第 4 个读者线程{开始}读
第 4 个读者线程{结束}读

【NEW】来了一位 读者
创建第 6 个读者线程去读
第 5 个读者线程正在{等待}读
第 5 个读者线程{开始}读
第 5 个读者线程{结束}读

【NEW】来了一位 读者
创建第 7 个读者线程去读
第 6 个读者线程正在{等待}读
第 6 个读者线程{开始}读
第 6 个读者线程{结束}读
第 7 个读者线程正在{等待}读
第 7 个读者线程{开始}读

【NEW】来了一位 读者
创建第 8 个读者线程去读
第 7 个读者线程{结束}读

【NEW】来了一位 读者
创建第 9 个读者线程去读
第 8 个读者线程正在{等待}读
第 8 个读者线程{开始}读
第 9 个读者线程正在{等待}读
第 9 个读者线程{开始}读
第 8 个读者线程{结束}读

【NEW】来了一位 写者
创建第 10 个写者线程去写
第 9 个读者线程{结束}读

【NEW】来了一位 读者
创建第 11 个读者线程去读
第 10 个写者线程{等待}写
第 10 个写者线程{开始}...
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值