寻找对我的读者/作家实施的批评
Looking for critique of my reader/writer implementation
我在C 11中实现了读者/作家问题…我想知道它是什么问题,因为这些事情很难自行预测。
- 共享数据库:
- 读者可以访问数据库时
- 当没有读者或作家时,作家可以访问数据库
- 一个线程一次操纵状态变量
该示例有3位读者和1位作家,但也使用2个或更多作家....
代码:
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;
}
反馈:
1
。它缺少所有必要的#includes。
2
。它假设using namespace std
在声明中是不好的样式,因为它用名称空间std污染了您所有的客户
3
。锁的发布并不例外:
write_lock();
data_base_variable++;
m.lock();
cout << "data_base_thread: " << thread_id << "...write: " << data_base_variable << endl;
m.unlock(); // leaked if an exception is thrown after m.lock()
write_unlock(); // leaked if an exception is thrown after write_lock()
4
。cout
在data_base_thread_write
中的m.lock()
包装确实是不必要的,因为write_lock()
应该已经提供了独家访问。但是我知道这只是一个演示。
5
。我 think 我在读/写逻辑中看到一个错误:
step 1 2 3 4 5 6
WR 0 1 1 1 0 0
AR 0 0 0 0 1 1
WW 0 0 1 1 1 0
AW 1 1 1 0 0 1
在步骤1中,线程1具有写锁。
在步骤2中,线程2尝试获取读取锁,增量WR
和第二个okToRead
上的块,等待AW == 0
。
在步骤3中,线程3尝试获取写锁,增量WW
和第二个okToWrite
上的块,等待AW == 0
。
在步骤4中,线程1版本,通过将AW
降低到0,并发出信号okToWrite
。
在步骤5中,线程2尽管没有发出信号,但 spuroly 都指出AW == 0
,并通过将WR
设置为0和AR
抓住读取锁定。
在步骤6中,线程3接收信号,指出AW == 0
,并通过将WW
设置为0和AW
和1。
在步骤6中,两个线程2拥有读取锁,线程3拥有写锁(同时)。
6
。类ReadersWriters
具有两个功能:
- 它实现了读/写utex。
- 它实现了线程执行的任务。
更好的设计将利用C 11中建立的静音/锁定框架:
用成员创建一个ReaderWriter
静音:
// unique ownership
void lock(); // write_lock
void unlock(); // write_unlock
// shared ownership
lock_shared(); // read_lock
unlock_shared(); // read_unlock
前两个名称lock
和unlock
与C 11 Mutex类型所使用的名称有目的地相同。只是这样做可以让您做以下事情:
std::lock_guard<ReaderWriter> lk1(mut);
// ...
std::unique_lock<ReaderWriter> lk2(mut);
// ...
std::condition_variable_any cv;
cv.wait(lk2); // wait using the write lock
,如果您添加:
void try_lock();
然后您也可以:
std::lock(lk2, <any other std or non-std locks>); // lock multiple locks
选择lock_shared
和unlock_shared
名称是因为当前C 1Y中的std::shared_lock<T>
类型(我们希望Y是4)工作草稿。它记录在N3659中。然后您可以说:
std::shared_lock<ReaderWriter> lk3(mut); // read_lock
std::condition_variable_any cv;
cv.wait(lk3); // wait using the read lock
即。通过创建一个独立的ReaderWriter
MUTEX类型,具有非常仔细的成员函数名称,您可以与STD定义的锁,condition_variable_any
和锁定算法获得互操作性。
有关此框架的更深入的理由,请参见N2406。
- 我的神经网络不起作用 [XOR 问题]
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 我的字符计数代码计算错误.为什么
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- cmake在我的项目中所需的所有静态库都不成功
- 为什么我的代码在输出中增加了93天
- 我的简单if-else语句是如何无法访问的代码
- 为什么我的for循环不能正确获取argv
- 我的项目不会像"undefined reference to `grpc::g_core_codegen_interface'"那样使用未定义的引用错误进行编译
- 0-1背包代码中的错误.我的代码中有什么错误
- 当我的阵列太大时出现分段错误
- 如何确认我的constexpr表达式实际上已经在编译时执行
- 为什么二进制搜索在我的测试中不起作用
- 如何指定我希望我的LIB链接到的DLL文件?-Visual Studio 2019
- 我的代码中有错误吗?使用BGI图形的C++代码对我不起作用
- 当我在main中声明了我的2d数组时,为什么我的程序会退出
- OpenGL在启用深度测试时不会丢弃我的碎片
- 为什么我的 std::ref 无法按预期工作?
- clang整洁10忽略了我的NOLINT命令
- 寻找对我的读者/作家实施的批评