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

时间:2015-11-10 01:40:32

标签: c++ multithreading c++11 vector

此代码挂起(仅在发布版本中,请注意)并且必须手动终止:

#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()的持续垃圾邮件似乎在某种程度上阻止了执行,但是如何以及为什么?为什么只在Release版本中?

(使用VC2013构建,如果这是一个因素。)

2 个答案:

答案 0 :(得分:3)

最可能的解释是优化器转动循环:

<script type="text/javascript" src="https://xxxx.yyy.appl.js"> </script>"

while (vec.size() > 0);

...将reg = vec.size(); while(reg > 0); 中的值加载到寄存器中并从那里读取它,因为循环中没有任何内容指示可能导致值可更改的内存屏障。

当你在循环中调用vec.size()时,调用涉及溢出寄存器,因此将值保存在寄存器中没有任何好处,所以没有完成。

答案 1 :(得分:1)

悬挂代码的问题是

while (vec.size() > 0);

与:

相同
while (vec.size() > 0)
{
}

这是一个持续调用相同内容的紧密循环 - 您的处理器重复调用此方法而不执行任何其他操作。

但是,这个:

while (vec.size() > 0) Sleep(1);

告诉处理器在一毫秒内什么都不做(即它正在休息,可能允许另一个进程在此期间运行在该核心上),然后再次调用该方法。

就像你在不间断的冲刺(悬挂代码)中跑得更快,而不是短跑,然后花一点时间休息,然后再次冲刺等(非悬挂)