I'm trying to solve the next problem:
There are two types of functions. The first type can execute from different threads simultaneously (for example - read data from container). The second one must block all threads inside first-type-function until some operation done (for example - change container).
I am sure this is an easy task, but I can't find a solution. Can anyone please help me?
This is simple example. I expect threads to stop output for 1 second every 3 seconds (I'm aware that this code is unsafe (cout from different threads), but it's just an simple example)
#include <iostream>
#include <thread>
#include <mutex>
using namespace std;
void f() {
// TODO: wait if g() locked this
cout << "Hello from thread " << this_thread::get_id() << endl;
this_thread::sleep_for(100ms);
}
void g() {
// TODO: some lock for f()
cout << "All threads must sleep at night" << endl;
this_thread::sleep_for(1000ms);
// TODO: unlock
}
int main() {
thread t1([]() { for (;;) f(); });
thread t2([]() { for (;;) f(); });
thread t3([]() { for (;;) f(); });
for (;;) {
this_thread::sleep_for(3000ms);
g();
}
return 0;
}
This is a common pattern best solved using reader/writer locks. In C++ you want to use std::shared_lock
and imagine that f
is a reader and g
is a writer.
Declare variable:
std::shared_mutex mutex;
In f
:
// Multiple threads can enter the shared lock (readers).
std::shared_lock lock(mutex);
In g
:
// Only one thread can enter the unique lock (writers).
std::unique_lock lock(mutex);