C#多线程的坑之代码变序

王朝学院·作者佚名  2016-08-27
窄屏简体版  字體: 小  |  中  |  大  |  超大  

英文好的,可跳过,直接打开底部的“参考“链接。

代码变序--reordering of memoryOperations

大概4年前,阅读了这篇文章后http://www.albahari.com/threading/,我就自我满足,多线程编程不过就是用那些工具而已。

今天,读了一篇文章后,http://msdn.microsoft.com/en-us/magazine/jj863136.aspx,才发现C#代码是可以变序的(上面的文章也提到了,忘得一干二净)。

举例,你写出如下的代码

void Init() { _data = 42; _initialized = true;}JIL运行时的代码却可以像这样(不是IL代码哦,IL编译出代码与源代码是一致的)

void Init() { _initialized = true; _data = 42;}这个坑爹的JIL优化,如果不注意,可能就不会抓住bug所在。底部有我写的再现方法。先别运行程序,试试猜猜结果有几种可能。

总结:浮躁+记忆力差是很致命的,必须要找适合自己的工作方式。深入理论上理解+上手验证,这样才算消化,也不容易忘。

不重复造轮子,更不能重复学习。

参考:

http://msdn.microsoft.com/en-us/magazine/jj863136.aspx

http://msdn.microsoft.com/en-us/magazine/jj883956.aspx

classPRogram

{staticvoidMain(string[] args)

{

DataInit di=newDataInit();newThread(() => { di.Init(); }) { IsBackground =true}.Start();newThread(() => { di.Print(); }) { IsBackground =true}.Start();

Console.WriteLine("Running... Press enter to quit");

Console.ReadLine();

}

}publicclassDataInit

{privateint_data =0;privatebool_initialized =false;//准备些无用的fieldprivatechar_c ='0';privateint_data1 =0;privateint_data2 =0;privateint_data3 =0;privateint_data4 =0;publicvoidInit()

{

_data=42;//Write 1_initialized =true;//Write 2//下面的field赋值是用来触发JIL 优化的,如何触发的原理,我不知道:(。///*try屏蔽下面的代码,结果很可能就是42了_c ='0';

_data1=0;

_data=0;

_data2=0;

_data3=0;

_data4=0;

}publicvoidPrint()

{

Console.WriteLine(_data);

Console.WriteLine(_initialized);if(_initialized)

{

Console.WriteLine(_data);//should 42,有时候确是0}else{

Console.WriteLine("Not initialized");

}

}

}

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航