下面讲的是读者写者问题中写者优先的实现过程
该问题需要满足:
- 读写互斥
- 写写互斥
- 读读不互斥
- 同时有读、写,写优先
需要用到两个全局变量,分别为:
writeCount:写者人数
readCount:读者人数
需要用到5个全局信号量,分别为:
mutex1:目的是控制每次只有一个写者进出写者队列。为1时,写者可以进或出队列,为0时,写者需等待
mutex2:目的是控制每次只有一个读者进出读者队列。为1时,读者可以进或出队列,为0时,读者需等待
mutex3:通过读者的RWMutex比mutex3后申请先释放,使得同种情况下写者比读者先获取RWMutex信号量(实现写者优先)
RWMutex:目的是控制读写互斥。第一个写者需要等待申请RWMutex信号量,以后的写者无需申请直到写者为空释放。而读者每次都需要申请RWMutex信号量,因此会优先写者操作。
wrt:保证每次只有一种类型对文件进行操作(类型1:一个写 类型2:一个读或多个读)
为1时,代表可以对文件进行操作,为0时,代表已有一种类型对文件进行操作。第一个读者需要等待申请wrt信号量,以后的读者无需申请直到读者为空释放。而写者每次都需要申请wrt信号量,因此实现了每次只能有一个写者对文件进行操作,可以有多个读者同时对文件进行操作。
写者的流程:
1.申请mutex1信号量,等待进入写者队列
2.进入队列后writeCount++,若writeCount为1需等待申请RWMutex信号量
3.成功进入写者队列后释放mutex1信号量
4.申请wrt信号量等待写操作
5.进行写操作
6.写入完毕后释放wrt信号量
7.申请mutex1信号量,等待出写者队列
8.出队列后writeCount—,若writeCount为0需释放RWMutex信号量
9.成功出队后释放mutex1信号量
读者的流程:
1.申请mutex3信号,作用是同时等待读者写者,使得写者优先获取RWMutex信号
2.申请RWMutex信号
3.申请mutex2信号,等待进入读者队列
4.进入队列后readCount++,若readCount为1则申请wrt信号量
5.成功进入队列后释放mutex2信号量
6.释放RWMutex信号量
7.释放mutex3信号量
8.进行读操作
9.申请mutex2信号量,等待出读者队列
10.出队列后readCount—,若readCount为0则释放掉wrt信号量
11.成功出队后释放mutex2信号量
举个例子:
/*************************************************************************
> File Name: p.cpp
> Author: Zcy
> Mail: [email protected]
> Created Time: 三 1/23 18:16:17 2019
************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
int readCount, writeCount;
sem_t mutex1, mutex2, mutex3, RWmutex, wrt;
struct node
{
int num, time1, time2;
};
void init() {
readCount = 0;
writeCount = 0;
sem_init(&mutex1, 0, 1);
sem_init(&mutex2, 0, 1);
sem_init(&mutex3, 0, 1);
sem_init(&RWmutex, 0, 1);
sem_init(&wrt, 0, 1);
}
void over() {
sem_destroy(&mutex1);
sem_destroy(&mutex2);
sem_destroy(&mutex3);
sem_destroy(&RWmutex);
sem_destroy(&wrt);
}
void* read_t(void *t) {
node *tt = (node *)t;
sleep(tt -> time1);
printf("reader %d: start run\n", tt -> num);
//进读者队列
sem_wait(&mutex3);
sem_wait(&RWmutex);
sem_wait(&mutex2);
readCount ++;
if (readCount == 1) {
sem_wait(&wrt);
}
sem_post(&mutex2);
sem_post(&RWmutex);
sem_post(&mutex3);
//读操作
printf("reader %d: start read\n", tt -> num);
sleep(tt -> time2);
printf("reader %d: end read\n", tt -> num);
//出读者队列
sem_wait(&mutex2);
readCount --;
if (readCount == 0) {
sem_post(&wrt);
}
sem_post(&mutex2);
pthread_exit(0);
}
void* write_t(void *t) {
node *tt = (node *)t;
sleep(tt -> time1);
printf("writer %d: start run\n", tt -> num);
//进写者队列
sem_wait(&mutex1);
writeCount ++;
if (writeCount == 1) {
sem_wait(&RWmutex);
}
sem_post(&mutex1);
//写操作
sem_wait(&wrt);
printf("writer %d: start write\n", tt -> num);
sleep(tt -> time2);
printf("writer %d: end write\n", tt -> num);
sem_post(&wrt);
//出写者队列
sem_wait(&mutex1);
writeCount --;
if (writeCount == 0) {
sem_post(&RWmutex);
}
sem_post(&mutex1);
pthread_exit(0);
}
int main () {
int num = 0;
pthread_t pid;
pthread_attr_t attr;
pthread_attr_init(&attr);
init();
while(scanf("%d", &num) != EOF) {
char chooes;
int time1, time2;
scanf("%c%d%d", &chooes, &time1, &time2);
node *t = (node *)malloc(sizeof(node));
t -> num = num;
t -> time1 = time1;
t -> time2 = time2;
if (chooes == 'R') {
printf("reader %d: start waiting\n", num);
pthread_create(&pid, &attr, read_t, t);
} else if(chooes == 'W') {
printf("writer %d: start waiting\n", num);
pthread_create(&pid, &attr, write_t, t);
}
}
over();
return 0;
}
此时结果为:
reader 1: start waiting
writer 2: start waiting
reader 3: start waiting
reader 4: start waiting
writer 5: start waiting
reader 1: start run
reader 1: start read
writer 2: start run
reader 3: start run
reader 4: start run
writer 5: start run
reader 1: end read
writer 2: start write
writer 2: end write
writer 5: start write
writer 5: end write
reader 3: start read
reader 4: start read
reader 3: end read
reader 4: end read
如果有写的不对或者不全面的地方 可通过主页的联系方式进行指正,谢谢