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