欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

读写者问题-写者优先

程序员文章站 2022-07-05 09:04:35
...

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

/*
* 	这是一个写者优先的读写者问题
*/
# 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 个写者线程{开始}...