【发布时间】:2014-02-03 21:31:00
【问题描述】:
我在 c++11 中实现了读写器问题……我想知道它有什么问题,因为这些事情我自己很难预测。
- 共享数据库:
- 没有作者时读者可以访问数据库
- 当没有读者或作者时,作者可以访问数据库
- 一次只有一个线程处理状态变量
示例有 3 个 reader 和 1 个 writer,但也使用 2 个或更多 writer....
代码:
class ReadersWriters {
private:
int AR; // number of active readers
int WR; // number of waiting readers
int AW; // number of active writers
int WW; // number of waiting writers
mutex lock;
mutex m;
condition_variable okToRead;
condition_variable okToWrite;
int data_base_variable;
public:
ReadersWriters() : AR(0), WR(0), AW(0), WW(0), data_base_variable(0) {}
void read_lock() {
unique_lock<mutex> l(lock);
WR++; // no writers exist
// is it safe to read?
okToRead.wait(l, [this](){ return WW == 0; });
okToRead.wait(l, [this](){ return AW == 0; });
WR--; // no longer waiting
AR++; // now we are active
}
void read_unlock() {
unique_lock<mutex> l(lock);
AR--; // no longer active
if (AR == 0 && WW > 0) { // no other active readers
okToWrite.notify_one(); // wake up one writer
}
}
void write_lock() {
unique_lock<mutex> l(lock);
WW++; // no active user exist
// is it safe to write?
okToWrite.wait(l, [this](){ return AR == 0; });
okToWrite.wait(l, [this](){ return AW == 0; });
WW--; // no longer waiting
AW++; // no we are active
}
void write_unlock() {
unique_lock<mutex> l(lock);
AW--; // no longer active
if (WW > 0) { // give priority to writers
okToWrite.notify_one(); // wake up one writer
}
else if (WR > 0) { // otherwize, wake reader
okToRead.notify_all(); // wake all readers
}
}
void data_base_thread_write(unsigned int thread_id) {
for (int i = 0; i < 10; i++) {
write_lock();
data_base_variable++;
m.lock();
cout << "data_base_thread: " << thread_id << "...write: " << data_base_variable << endl;
m.unlock();
write_unlock();
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
}
void data_base_thread_read(unsigned int thread_id) {
for (int i = 0; i < 10; i++) {
read_lock();
m.lock();
cout << "data_base_thread: " << thread_id << "...read: " << data_base_variable << endl;
m.unlock();
read_unlock();
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
}
};
int main() {
// your code goes here
ReadersWriters rw;
thread w1(&ReadersWriters::data_base_thread_write, &rw, 0);
thread r1(&ReadersWriters::data_base_thread_read, &rw, 1);
thread r2(&ReadersWriters::data_base_thread_read, &rw, 2);
thread r3(&ReadersWriters::data_base_thread_read, &rw, 3);
w1.join();
r1.join();
r2.join();
r3.join();
cout << "\nThreads successfully completed..." << endl;
return 0;
}
【问题讨论】:
-
“给我反馈代码。”....听起来你应该把它放在 codereview.stackexchange.com
-
这个问题似乎是题外话,因为它属于 codereview.stackexchange.com
-
为什么我不能在这里问它,因为它是一个设计问题?
-
这个问题很重要,因为它还询问如何与 C++11 互斥 API 进行互操作。你只需要更深入地阅读才能意识到这一点。这里唯一犯下的“罪行”是问题中开头句的不幸措辞,引发了题外话。我已投票决定重新开放并敦促其他人也这样做。归根结底,SO 应该很有用。把这个问题追到姐妹网站也没有用。我的回复包含的信息将对 SO 上的大量 C++ 编码人员有所帮助。
-
@HowardHinnant 抱歉,我在这里没有看到任何其他问题,但“请给我一些反馈”。如果您认为可以将其编辑为适当的问题,请这样做。我没有看到这个问题,因此即使重新开放,也会有另外 5 名投票者接近并关闭它。就目前而言,收盘似乎完全合理。
标签: c++ multithreading algorithm c++11 locking