c++ - std::mutex 没有为 std::cout 正确锁定

标签 c++ multithreading c++11

我正在学习 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

除了互斥量显然没有正确锁定之外,令人困惑的是它总是被切成两半的 Hello1。

编辑:在 VS2015 中完成,如果有任何不同(不应该,因为它都是标准的?)

最佳答案

您需要使用 static ,因为所有线程都必须访问同一个互斥对象。另外,try_lock() (或 lock() )如果在到达 unlock() 之前抛出异常,则会导致问题. std::lock_guard<>()这样做是一种更安全的方法并被推荐,因为当您超出其范围时它会被释放,无论是通过函数返回还是通过异常。

尝试对函数进行以下修改:

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);

关于c++ - std::mutex 没有为 std::cout 正确锁定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36466008/

相关文章:

C++ 将字符串转换为 typedef 或 istream 重载

c++ - C++ 中的函数拆分?

javascript - WebAssembly 从 wasm 调用 JavaScript 方法,即在 C++ 代码中

c++ - 一旦客户端断开连接,服务器应用程序就会崩溃

C++ 正则表达式和占位符

c++ - 为什么我不能在绑定(bind)中使用 mem_fn Functor?

c++ - 是否可以使您自己的 winapi 函数(如 getpixel)在 Windows 上工作?

c++ - 错误 : C2146: syntax error : missing ';' before identifier 'm_Employer' ,

ios - 如何暂停 dispatch_queue_t 及其创建的队列

linux - 来自现有类的 C++11 线程