我有一个应用程序,其中一些STL容器在3个线程中读取,并用2写入。我知道有多线程容器的TBB,但它不是我的应用程序中的一个选项。
所以我想用std :: mutex和我的双手使程序线程安全。这是我所做的简单版本:
int readers = 0;
std::mutex write;
// One write, no reads.
void write_fun()
{
write.lock();// We lock the resource
while(readers > 0){}// We wait till everyone finishes read.
// DO WRITE
write.unlock();// Release
}
// Multiple reads, no write
void read_fun()
{
// We wait if it is being written.
while(!write.try_lock()){}
write.unlock();
readers++;
// do read
readers--;
}
这是在C ++ 11中执行此操作的正确方法吗?
答案 0 :(得分:36)
非常接近,需要注意的事项,在c ++中为了异常安全性和可读性,IMO,使用RAII锁是件好事。你真正需要的是一个shared_mutex,比如在boost或c ++ 14中。
std::shared_mutex write; //use boost's or c++14
// One write, no reads.
void write_fun()
{
std::lock_guard<std::shared_mutex> lock(write);
// DO WRITE
}
// Multiple reads, no write
void read_fun()
{
std::shared_lock<std::shared_mutex> lock(write);
// do read
}
如果您不想使用boost @howardhinmant,请提供指向reference implementation的链接
答案 1 :(得分:7)
这是安全的,但仍然可能不公平或无效:
std::atomic<int> readers;
std::mutex write;
// One write, no reads.
void write_fun()
{
write.lock();// We lock the resource
while(readers > 0){}// We wait till everyone finishes read.
// DO WRITE
write.unlock();// Release
}
// Multiple reads, no write
void read_fun()
{
// We wait if it is being written.
write.lock();
readers++;
write.unlock();
// do read
readers--;
}
具有条件变量的解决方案可以避免忙于等待readers
降为0,作为读者的练习。