0%

读者写者问题

允许多个进程同时对数据进行读操作,但是不允许读和写以及写和写操作同时发生。

一个整型变量 count 记录在对数据进行读操作的进程数量,一个互斥量 count_mutex 用于对 count 加锁,一个互斥量 data_mutex 用于对读写的数据加锁。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
typedef int samephore;

void down(int* x){}
void up(int* y){}

int count = 0;
samephore count_mutex = 1;
samephore data_mutex = 1;

void reader(){
while(true){

down(&count_mutex);
count ++;
if(count==1) down(&data_mutex);
up(&count_mutex);
//read
down(&count_mutex);
count --;
if(count==0) up(&data_mutex);
up(&count_mutex);
}
}
void writer(){
while(true){
down(&data_mutex);
//write
up(&data_mutex);
}
}

此解法中读者是优先的,当存在读者时,写者将被延迟,且只要有一个读者活跃,随后而来的读者都将被允许访问此文件,从而导致写者长时间等待,并有可能出现写者饥饿现象。

增加信号量并修改此程序,让写者与读者平等:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
samephore s = 1;

void reader(){
while(true){
down(&s);
down(&count_mutex);
count ++;
if(count==1) down(&data_mutex);
up(&count_mutex);
up(&s);

//read

down(&count_mutex);
count --;
if(count==0) up(&data_mutex);
up(&count_mutex);
}
}
void writer(){
while(true){
down(&s);
down(&data_mutex);
//write
up(&data_mutex);
up(&s);
}
}

假设进程队列:R1、W1、W2、R2、R3

当R1刚刚执行完V(s),W1进程若调度会卡在P(writeblock),而W2R2R3想要运行,均会卡在P(s),当R1读完,V(writeblock)完成,W1可以运行,以此类推,R1W1W2R2R3按顺序调度。

Welcome to my other publishing channels