查了下MSDN的解釋:
MemoryBarrier is required only on multiprocessor systems with weak memory ordering (for example, a system employing multiple Intel Itanium processors). Synchronizes memory access as follows: The processor executing the current thread cannot reorder instructions in such a way that memory accesses prior to the call to MemoryBarrier execute after memory accesses that follow the call to MemoryBarrier. 就是說多核處理器會對運行CPU指令順序重排優化,MemoryBarrier可以阻止指令重排,調用Thread.MemoryBarrier()之后的代碼中內存訪問不能再這之前就完成了。也就是它可以限制指令重排和內存讀寫的緩存。 下面有段代碼,在release編譯情況下會死循環(debug應該是沒做instructions reorder而不會有問題) bool complete = false; var t = new Thread(() => { bool toggle = false; while (!complete) toggle = !toggle; }); t.Start(); Thread.Sleep(1000); complete = true; t.Join();
問題原因:
1.編譯器、CLR或者CPU可能重新排序了程序指令,以此提高效率。
2.編譯器、CLR或者CPU引入緩存優化導致其他的線程不能馬上看到變量值的更改。
嘗試了下將Thread.MomoryBarrier加到while中,保證complete讀到的最新的:
此例子中MomoryBarrier 應該時解決jit時過度優化,雖然兩個核心cache line 不會及時同步,complete 值修改通過MSIE協議也很快的通知到其他核心。
出現死循環在于jit 任魏complete值一直是false,并沒有執行load操作,而是直接判斷true跳轉。
bool complete = false; var t = new Thread(() => { bool toggle = false; while (!complete) { Thread.MemoryBarrier(); toggle = !toggle; } }); t.Start(); Thread.Sleep(1000); complete = true; t.Join();
在看一個例子:(來自《window 并發編程指南》內存模型部分) MyObject mo= ..; int f= mo.field; if(f==0) { //same operation console.writeline(f); } 如果mo.field 在讀取和Console.WriteLine相隔足夠遠,那么編譯器可能會認為讀mo.field 讀取兩遍會更有效,被編譯成如下代碼: MyObject mo= ..; if(mo.filed==0) { //same operation Console.WriteLine(mo.field); } 編譯器可能判斷,保留這個值是否給寄存器帶來壓力并導致??臻g的低效使用,并且之個分支是否很少被使用(因此f值就不需要多次) 這樣帶來多線程問題,將f值使用volatitle修飾,可禁止這種優化
我看:多線程才會出現吧!!
157894.html
本文由 貴州做網站公司 整理發布,部分圖文來源于互聯網,如有侵權,請聯系我們刪除,謝謝!
網絡推廣與網站優化公司(網絡優化與推廣專家)作為數字營銷領域的核心服務提供方,其價值在于通過技術手段與策略規劃幫助企業提升線上曝光度、用戶轉化率及品牌影響力。這...
在當今數字化時代,公司網站已成為企業展示形象、傳遞信息和開展業務的重要平臺。然而,對于許多公司來說,網站建設的價格是一個關鍵考量因素。本文將圍繞“公司網站建設價...
在當今的數字化時代,企業網站已成為企業展示形象、吸引客戶和開展業務的重要平臺。然而,對于許多中小企業來說,高昂的網站建設費用可能會成為其發展的瓶頸。幸運的是,隨...
在windows安裝器里,使用bootsect.exe更新引導是什么意思,有什么作用,有必要開啟嗎?如有必要,此更新引導指將新安裝的系統添加到引導菜單。如果您不選擇它,您將無法選擇啟動新安裝的系統...
世界公認十大名刀 世界十大名刀有哪些?世界三大名刀之首? 1、歷史上最殘忍的刀,隕石鐵,質地堅硬,古羅馬刑事專用,但歷史記載,很少使用,因為很多人害怕死2、阿拉斯加獵戶刀王的阿拉斯加獵戶刀,只有徒手殺熊五只以上的人才能得到3、穆斯林腕刀只用于宰牲節開幕式4、阿富汗彎刀,別以為這是藝術品,其實刀口很鋒利,所以主人放了專門的刀架5、典型的實用刀比瑞士軍刀好6、芬蘭軍刀,芬蘭山地師范學院7、炎熱的夏...
自制洗發水怎樣才能變稠?一般洗發水里都會添加凝膠,一種透明的液體凝膠。加入凝膠會使洗發水變粘。不使用啫喱的話,一般的洗發水不會起泡,也不會發粘!這種膠水是允許在化學藥品中添加的,使用后起到豐富泡沫的作用,所以洗發水正常添加是合法的事情!自制洗發水怎樣才能變稠?可以加一點面粉,如果沒有,也可以加一點面粉起子。加幾次,加一點點,一點點。如果太稠,可以再加點水。加入面粉后,除灰去油能力更強。而且還能有一...