2017-04-12 40 views
1

我正在学习C++中的多线程并刚刚发现互斥锁。我的代码如下:C++意外的多线程行为

#include "stdafx.h" 
#include <thread> 
#include <iostream> 
#include <string> 
#include <mutex> 
using namespace std; 

std::mutex mu; 

void shared_print(string msg, int i) { 
    std::lock_guard<std::mutex> guard(mu); 
    cout << msg << i << endl; 
} 

void function_1() { 
    for (int i = 0; i > -3; i--) 
     shared_print("Thread1: ", i); 
} 

int main() { 
    std::thread thread1(function_1); 

    for (int i = 0; i < 3; i++) 
     shared_print("Main: ", i); 

    thread1.join(); 
    return 0; 
} 

从我的理解中,互斥锁一次只允许访问一个资源。所以互斥量将被第一个调用它的线程锁定(Thread1)。当main线程尝试访问互斥锁时,它将被阻止,直到互斥锁被解锁为Thread1。一旦cout执行后,它将被解除阻塞,其中main将被允许执行。

我希望得到的结果进行交错的呼叫如Thread1, Main, Thread1, Main

然而,而是我得到标准输出下面的结果。该模式仍然是任何迭代次数相同:

Thread1: 0 
Thread1: -1 
Thread1: -2 
Main: 0 
Main: 1 
Main: 2 
+0

为什么它会交错?没有您的代码强制执行的命令。如果一个线程仍然有CPU时间,它可以获得刚刚释放的锁。 – Arash

回答

2

首先认识到,执行的顺序是不确定的,所以你得到了什么是完全有效的 - 并且在下一次运行它的时候,你可能会得到完全不同的顺序。

我增加迭代的次数每个线程运行32的是,在过去的几个迭代是这样的:

Thread1: -22 
Main: 22 
Thread1: -23 
Main: 23 
Main: 24 
Thread1: -24 
Main: 25 
Thread1: -25 
Main: 26 
Thread1: -26 
Main: 27 
Thread1: -27 
Thread1: -28 
Thread1: -29 
Main: 28 
Main: 29 
Main: 30 
Main: 31 
Thread1: -30 
Thread1: -31 

所以,有时我们得到交错,其他时候我们得到短期运行(4在这种情况下是最长的)来自一个线程。其他时候,我运行它,我得到了完美的交错,所以整个事件作为线程1的一个输出,然后是来自Main的一个输出,然后重复。

底线:您的代码按预期工作。