我正在学习C++ 11中的多线程,并且尝试了这个简单的测试,但是输出不是我期望的。

#include <thread>
#include <iostream>
#include <mutex>

int main() {
    auto function = [](int x) {
        std::mutex m;
        m.try_lock();
        std::cout << "Hello" << x << std::endl;
        m.unlock();
        return;
    };
    std::thread t1(function , 1);
    std::thread t2(function, 2);
    std::thread t3(function, 3);
    std::thread t4(function, 4);

    t1.join();
    t2.join();
    t3.join();
    t4.join();

    std::cin.get();
    return 0;
}

我期望输出为:
Hello1
Hello2
Hello3
Hello4

(也许不是按此顺序,而是每个问候和数字在单独的行中)

相反,我得到了这样的东西:
HelloHello21
Hello3
Hello4

要么
HelloHello2
1
Hello3
Hello4

除了互斥锁显然不能正确锁定之外,还有一个令人困惑的问题是,总是Hello2被切成两半。

编辑:如果有任何区别,请在VS2015中完成(不应该因为它全部是标准格式?)

最佳答案

您需要使用static,因为所有线程都必须访问相同的互斥对象。另外,如果在到达try_lock()之前抛出异常,lock()(或unlock())也会引起问题。 std::lock_guard<>()是一种更安全的方法,因此建议使用ojit_code,因为无论是通过函数返回还是通过异常,它都将在超出范围时被释放。

尝试对该功能进行以下修订:

auto function = [](int x) {
    static std::mutex m;
    std::lock_guard<std::mutex> mylock(m);
    std::cout << "Hello" << x << std::endl;
    return;
};

有关更多信息,请参见http://en.cppreference.com/w/cpp/thread/lock_guard

另外,如果您认为将来可能会更改互斥锁类型(或只是想花哨),则可以使用推断的模板类型设置互斥锁:
std::lock_guard<decltype(m)> mylock(m);

08-17 04:26