可以请有人解释我为什么这个程序中的两个线程(当使用Visual Studio 2012/2013附带的编译器编译时)被阻塞,直到两个std::call_once调用都被执行?另一个Visual Studio错误(假设它在使用GCC编译时表现如预期)?有人可以想出一个解决方法吗?想象一下我所经历的所有痛苦,以解决问题,并请,仁慈.
#include <chrono>
#include <iostream>
#include <mutex>
#include <thread>
namespace
{
std::once_flag did_nothing;
void do_nothing()
{ }
void sleep_shorter_and_do_nothing_once()
{
std::this_thread::sleep_for(std::chrono::seconds(3));
std::cout << "1\n";
std::call_once(did_nothing, do_nothing);
std::cout << "2\n";
}
std::once_flag sleeped_longer;
void sleep_longer()
{
std::this_thread::sleep_for(std::chrono::seconds(10));
}
void sleep_longer_once()
{
std::cout << "3\n";
std::call_once(sleeped_longer, sleep_longer);
std::cout << "4\n";
}
}
int main()
{
std::thread t1(sleep_shorter_and_do_nothing_once);
std::thread t2(sleep_longer_once);
t1.join();
t2.join();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
详细说明,它在使用GCC编译时表现如预期:
使用Visual Studio 2012/2013附带的编译器进行编译时,其行为如下:
我写了一个小测试项目,看看在执行callable时std :: call_once是否阻塞。项目的输出允许假设call_once有2个行为:它在分离的线程上阻塞,而在join上不阻塞。我强烈怀疑这不可能成立,但是我无法得出其他结论,请指导我做出正确的结论。
using namespace std;
once_flag f;
mutex cout_sync;
void my_pause()
{
volatile int x = 0;
for(int i=0; i<2'000'000'000; ++i) { x++; }
}
void thr(int id)
{
auto start = chrono::system_clock::now();
call_once(f, my_pause);
auto end = chrono::system_clock::now();
scoped_lock l{cout_sync};
cout << "Thread " << id << " finished in " << (static_cast<chrono::duration<double>>(end-start)).count() << " sec" << endl;
}
int main()
{
vector<thread> threads;
for(int i=0; i<4; …Run Code Online (Sandbox Code Playgroud)