繁体   English   中英

std :: mutex无法正确锁定std :: cout

[英]std::mutex not locking properly for std::cout

我正在学习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 ,因为所有线程都必须访问相同的互斥对象。 另外,如果在您unlock()之前引发了异常, try_lock() (或lock() )也会引起问题。 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);

try_lock()不一定锁定互斥体。 它可能会锁定互斥锁,但可能不会。 它只会尝试锁定互斥锁。 如果已被锁定,则它不会等到互斥锁被解锁后才返回,表明已发生这种情况。

因此,实际上,您的代码最终无法有效地以任何形式,形状,物质或形式同步其输出。

如果您确实想锁定互斥锁,请使用lock()而不是try_lock()

编辑:正如其他人指出的那样,您的代码有效地为每个线程创建了一个单独的互斥体,因此您也需要使该互斥体成为static

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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