2017-02-03 5 views
0

ich diesen Beispielcode haben:std :: Mutex syncronization zwischen Threads

//#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 

Wenn ich Kommentar- 1ms schlafe ich erwartete Arbeits erhalten:

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 verstehe nicht, wie Thread 0 kann lock() & unlock() Mutex, wenn Faden 1 wird in einem mutex.lock() blockiert ...

std::this_thread::yield() Verwendung von I einen Unterschied nicht sehen kann (in Win32) aber std::this_thread::sleep_for(std::chrono::milliseconds(1)) scheint ... zu arbeiten

mit C++ 14/17 std::shared_timed_mutex und std::shared_mutex und lock_shared()/unlock_shared() Ich erwarte Ergebnis ...

eine Beratung/Erklärung?

+0

Verwenden Sie einfach im Vorbeigehen 'std :: lock_guard', um einen Mutex zu sperren. Sein Destruktor wird den Mutex entsperren, so dass Sie nicht explizit 'unlock' aufrufen müssen; das ist eine gute Sache, wenn der Code in der gesperrten Region eine Ausnahme auslöst. –

+0

Ich verwende immer std :: lock_guard lock (g_num_mutex); ... das ist nur eine Demo, um dieses "Feature" von std :: mutex zu demonstrieren –

Antwort

1

Sie halten den Mutex beim Schlafen fest; Der Mutex wird jeweils für mehrere Nanosekunden entsperrt. Wenn das System Thread 2 in diesen paar Nanosekunden nicht überprüft (und warum?), Erhalten Sie das beobachtete Ergebnis.

Ein C++ Mutex ist nicht fair. Wenn Sie versuchen, es zu sperren, werden Sie nicht nur abgelehnt, weil Sie der letzte Thread waren, um es zu sperren.

Verwandte Themen