-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathreader_writer.cpp
202 lines (181 loc) · 4.18 KB
/
reader_writer.cpp
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
/*
implementation of reader && writer
*/
#include <iostream>
#include <condition_variable>
#ifndef windows
#include<Windows.h>
struct mutex_t {};
#else
#include<pthread.h>
#endif
namespace pjssaber{
// Using condition-variable
template<typename T>
class first_type {
public:
// first type reader writer
// no reader shall be kept waiting if the share is currently opened for reading. This is also called readers-preference
int cnt = 0;
sem_t mutex, wr; // both initial to 1
// wr 用互斥 写 和 所有的读; mutex用于互斥 读之间
void reader()
{
lock(mutex);
cnt++;
if (cnt == 1) {
lock(wr);
}
unlock(mutex);
/*
do read
*/
lock(mutex);
cnt--;
if (cnt == 0) {
unlock(wr);
}
unlock(mutex);
}
void writer()
{
while (1) {
lock(wr); //lock
/*
critical , do write
*/
unlock(wr);
}
}
};
// csapp 12.19
class first_type_enhaunced {
public:
// first type reader writer
// no reader shall be kept waiting if the share is currently opened for reading. This is also called readers-preference
// 弱读者优先级; 因为读者unlock 后, 可能会唤醒另外一个读者; 那么考虑条件变量!! 用mutex 和 条件变量就能实现semaphore哦!
int cnt = 0;
sem_t mutex, wr; // both initial to 1
// wr 用互斥 写 和 所有的读; mutex用于互斥 读之间
cond_t cv;
void reader()
{
lock(mutex);
cnt++;
if (cnt == 1) {
lock(wr);
}
unlock(mutex);
/*
do read
*/
lock(mutex);
cnt--;
if (cnt == 0) {
unlock(wr);
cond_broadcast(&cv);
}
unlock(mutex);
}
void writer()
{
while (1) {
lock(wr); //lock
while (!(cnt == 0)) {
cond_wait(&cv, &wr);
}
/*
critical , do write
*/
unlock(wr);
}
}
};
// csapp 12.20 at most N readers. equal optunity for writer & reader
class universal {
public:
const int maxi = 100;
int cnt = 0;
sem_t mutex, wr; // both initial to 1
sem_t read; initia(&read, maxi)// initai to max
void reader()
{
lock(read);
lock(mutex);
cnt++;
if (cnt == 1) {
lock(wr);
}
unlock(mutex);
/*
do read
*/
lock(mutex);
cnt--;
if (cnt == 0) {
unlock(wr);
}
unlock(mutex);
unlock(read);
}
void writer()
{
while (1) {
lock(wr); //lock
/*
critical , do write
*/
unlock(wr);
}
}
};
// csapp 12.21 second type
// no writer, once added to the queue, shall be kept waiting longer than absolutely necessary. This is also called writers-preference
class writer_first {
int cnt = 0, wr_cnt = 0;
sem_t rd_lock, rd_stage1, // stage1 to block reader
wr, wr_lock; // both initial to 1
void reader()
{
lock(rd_stage1); // try to acquire resource
lock(mutex);
cnt++;
if (cnt == 1) {
lock(wr);
}
unlock(mutex);
unlock(rd_stage1);
/*
do read
*/
lock(mutex);
cnt--;
if (cnt == 0) {
unlock(wr);
}
unlock(mutex);
}
void writer()
{
while (1) {
lock(wr_lock);
wr_cnt++;
if (wr_cnt == 1) {
lock(rd_stage1);
}
unlock(wr_lock); // like reader do to
lock(wr); //lock
/*
critical , do write
*/
unlock(wr);
lock(wr_lock);
wr_cnt--
if (wr_cnt == 0) {
unlock(rd_stage1);
}
unlock(wr_lock); // like reader do to
}
}
};
}