问题
I have an application, where some STL containers are read in 3 threads, and written in 2. I know there is TBB for multi-threaded containers, but it is not an option in my application.
So I want to make the program thread-safe using std::mutex and my bare hands. This is a simple version of what I did:
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--;
}
Is this the correct way to do this in C++11?
回答1:
Pretty close, couple things to note, in c++ for exception safety and readability, IMO, it is good to use RAII locks. What you really need is a shared_mutex like in boost or coming in 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
}
If you don't want to use boost @howardhinmant was do kind as to give a link to a reference implementation
回答2:
This is safe, but still likely not fair or performant:
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--;
}
A solution with condition variables could avoid busy waiting for readers
to fall to 0, left as an exercise for the reader.
来源:https://stackoverflow.com/questions/19915152/c11-multiple-read-and-one-write-thread-mutex