简体   繁体   中英

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?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM