Reputation: 676
This code hangs (only in Release build, mind you) and must be terminated manually:
#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;
}
Whereas this code terminates naturally:
#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;
}
It seems that continuous spamming of std::vector<int>::size()
is blocking execution somehow, but how and why? And why only in Release build?
(Built with VC2013, if that is a factor.)
Upvotes: 1
Views: 241
Reputation: 126203
The most likely explanation is that the optimizer turns the loop:
while (vec.size() > 0);
into
reg = vec.size(); while(reg > 0);
...loading the value from vec.size()
into a register and just reading it from there, since there is nothing in the loop that indicates a memory barrier that might cause the value to be changeable.
When you put a Sleep
call in the loop, the call involves spilling registers, so saving the value in the register provides no benefit, so isn't done.
Upvotes: 3
Reputation: 314
The hanging code's problem is
while (vec.size() > 0);
which is the same as:
while (vec.size() > 0)
{
}
this is a tight loop continuously calling the same thing - your processor is repeatedly calling this method without doing anything else.
However, this:
while (vec.size() > 0) Sleep(1);
is telling the processor to do nothing for a millisecond (i.e. it's taking a break, likely allowing another process to run on this core in the meantime), and then calls the method again.
It's like you running as fast as you can in a non-stop sprint (hanging code), versus sprinting for a bit, then taking a moment to rest, then sprinting again, etc (non-hanging)
Upvotes: 1