I have the following code:
#include <chrono>
#include <iostream>
#include <mutex>
#include <thread>
int shared_var {0};
std::mutex shared_mutex;
void task_1()
{
while (true)
{
shared_mutex.lock();
const auto temp = shared_var;
std::this_thread::sleep_for(std::chrono::seconds(1));
if(temp == shared_var)
{
//do something
}
else
{
const auto timenow = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
std::cout << ctime(&timenow) << ": Data race at task_1: shared resource corrupt \n";
std::cout << "Actual value: " << shared_var << "Expected value: " << temp << "\n";
}
shared_mutex.unlock();
}
}
void task_2()
{
while (true)
{
std::this_thread::sleep_for(std::chrono::seconds(2));
++shared_var;
}
}
int main()
{
auto task_1_thread = std::thread(task_1);
auto task_2_thread = std::thread(task_2);
task_1_thread.join();
task_2_thread.join();
return 0;
}
shared_var
is protected in task_1
but not protected in task_2
What is expected:
I was expecting else
branch is not entered in task_1
as the shared resource is locked.
What actually happens:
Running this code will enter else
branch in task_1
.
Expected outcome is obtained when replace shared_mutex.lock();
with std::lock_guard<std::mutex> lock(shared_mutex);
and shared_mutex.unlock();
with std::lock_guard<std::mutex> unlock(shared_mutex);
Questions:
- What is the problem in my current approach?
- Why does it work with loack_guard?
I am running the code on: https://www.onlinegdb.com/online_c++_compiler