[英]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.