繁体   English   中英

与std :: vector <> :: size()并发

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

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