Miguel Angel Pons
Miguel Angel Pons

Reputation: 1152

std::mutex syncronization between threads

I have this sample code:

//#include "stdafx.h"    
#include <iostream>
#include <chrono>
#include <thread>
#include <mutex>


int g_num = 0;  // protected by g_num_mutex
std::mutex g_num_mutex;

void slow_increment(int id)
{
    std::cout << id << " STARTED\n";
    for (int i = 0; i < 100; ++i) {
        g_num_mutex.lock(); //STARTLOOP
        ++g_num;
        std::cout << id << " => " << g_num << '\n';
        std::this_thread::sleep_for(std::chrono::seconds(1));
        g_num_mutex.unlock();//ENDLOOP
       // std::this_thread::sleep_for(std::chrono::milliseconds(1));//UNCOMMENT THIS LINE TO GET A CORRECT WORKING
    }
}

int main()
{
    std::thread t1(slow_increment, 0);
    std::this_thread::sleep_for(std::chrono::seconds(6));
    std::thread t2(slow_increment, 1);
    t1.join();
    t2.join();
    return 0;
}

OUTPUT:

 0 STARTED
 0 => 1
 0 => 2
 0 => 3
 0 => 4
 0 => 5
 0 => 6
 1 STARTED // mutex.lock() is done?
 0 => 7
 0 => 8
 0 => 9
 0 => 10
 1 => 11 //aleatory number

If I uncomment 1ms sleep I get expected working:

0 STARTED
0 => 1
0 => 2
0 => 3
0 => 4
0 => 5
0 => 6
1 STARTED
1 => 7
0 => 8
1 => 9
0 => 10
1 => 11

I don't understand how thread 0 can lock() & unlock() mutex, when thread 1 is blocked in a mutex.lock()...

Using std::this_thread::yield() I can't see any difference (in win32) but std::this_thread::sleep_for(std::chrono::milliseconds(1)) seems to work...

with C++14/17 std::shared_timed_mutex and std::shared_mutex, and lock_shared()/unlock_shared() I get expected result...

any advice/explanation?

Upvotes: 0

Views: 133

Answers (1)

MSalters
MSalters

Reputation: 179787

You hold the mutex while sleeping; the mutex is unlocked for nanoseconds at a time. If the system doesn't check thread 2 in those few nanoseconds (and why would it?) then you get the observed outcome.

A C++ mutex isn't fair. If you try to lock it, you won't be denied merely because you were the last thread to lock it.

Upvotes: 1

Related Questions