[英]Concurrency with std::vector<>::size()
这段代码挂起(请注意,仅在发布版本中),必须手动终止:
#include <Windows.h>
#include <vector>
#include <thread>
int main()
{
std::vector<int> vec;
vec.push_back( 0 );
std::thread( [&vec]()
{
Sleep( 150 );
vec.pop_back();
} ).detach();
while( vec.size() > 0 );
return 0;
}
而此代码自然终止:
#include <Windows.h>
#include <vector>
#include <thread>
int main()
{
std::vector<int> vec;
vec.push_back( 0 );
std::thread( [&vec]()
{
Sleep( 150 );
vec.pop_back();
} ).detach();
while( vec.size() > 0 )
{
Sleep( 1 );
}
return 0;
}
似乎std::vector<int>::size()
持续垃圾邮件以某种方式阻止了执行,但是如何以及为什么呢? 为什么只在发布版本中?
(如果这是一个因素,则与VC2013一起内置。)
最可能的解释是优化器会循环:
while (vec.size() > 0);
进入
reg = vec.size(); while(reg > 0);
...将值从vec.size()
加载到寄存器中并从那里读取,因为循环中没有任何内容指示可能导致值更改的内存屏障。
当您将Sleep
调用放入循环中时,该调用涉及溢出寄存器,因此将值保存在寄存器中不会带来任何好处,因此无法完成。
吊码的问题是
while (vec.size() > 0);
与以下内容相同:
while (vec.size() > 0)
{
}
这是一个连续不断地调用同一事物的紧密循环-您的处理器反复调用此方法,而无需执行其他任何操作。
但是,这:
while (vec.size() > 0) Sleep(1);
告诉处理器一毫秒之内什么也不做(即正在休息,可能同时允许另一个进程在该内核上运行),然后再次调用该方法。
就像您在不间断的sprint(挂起代码)中以最快的速度运行,而不是先冲刺,然后花点时间休息,然后再次冲刺,等等(不挂起)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.