• [织梦吧]唯一域名:www.dedecms8.com,织梦DedeCMS学习平台.

当前位置: > 编程与数据库 > net编程 >

NET并行(多核)编程系列之七 共享数据问题和解决概述(2)

来源: www.dedecms8.com 编辑:织梦吧 时间:2012-06-27点击:

数据竞争

如果大家对多线程编程比较熟悉,就知道上面情况的产生是因为 “共享数据竞争”导致的(对多线程不熟悉不清楚的朋友也不用担心)。当有两个或者更多的task在运行并且操作同一个共享公共数据的时候,就存在潜在的竞争。如果不合理的处理竞争问题,就会出现上面意想不到的情况。

下面就来分析一下:上面代码的情况是怎么产生的。

当在把account对象的Balance进行自增的时候,一般执行下面的三个步骤:

读取现在account对象的Balance属性的值。

计算,创建一个临时的新变量,并且把Balance属性的值赋值给新的变量,而且把新变量的值增加1

把新变量的值再次赋给account的Balance属性

在理论上面,上面的三个步骤是代码的执行步骤,但是实际中,由于编译器,.NET 运行时对自增操作的优化操作,和操作系统等的因素,在执行上面代码的时候,并不一定是按照我们设想的那样运行的,但是为了分析的方便,我们还是假设代码是按照上面的三个步骤运行的。

之前的代码每次执行一次,执行代码的计算机就每次处于不同的状态:CPU的忙碌状况不同,内存的剩余多少不同,等等,所以每次代码的运行,计算机不可能处于完全一样的环境中。

在下面的图中,显示了两个task之间是如何发生竞争的。当两个task启动了之后(虽然说是并行运算,但是不管这样,两个的task的执行时间不可能完全一样,也就是说,不可能恰好就是同时开始执行的,起码在开始执行的时间上是有一点点的差异的)。 1.首先Task1读取到当前的balance的值为0。

2.然后,task2运行了,并且也读取到当前的balance值为0。

3.两个task都把balance的值加1

4.Task1把balance的值加1后,把新的值保存到了balance中

5.Task2 也把新的保存到了balance中

所以,结果就是:虽然两个task 都为balance加1,但是balance的值还是1。

通过这个例子,相信大家应该清楚,为什么上面的10个task执行1000,而执行后的结果不是10000了。

2.解决方案提出

数据竞争就好比一个生日party。其中,每一个task都是参加party的人,当生日蛋糕出来之后,每个人都兴奋了。如果此时,所有的人都一起冲过去拿属于他们自己的那块蛋糕,此时party就一团糟了,没有如何顺序。

在之前的图示例讲解中,balance那个属性就好比蛋糕,因为task1,task2都要得到它,然后进行运算。当我们来让多个task共享一个数据时就可能出现问题。下面列出了四种解决方案:

1.顺序执行:也就是让第一个task执行完成之后,再执行第二个。

2.数据不变:我们让task不能修改数据。

About D8

  • ©2014 织梦吧(d8) DedeCMS学习交流平台
  • 唯一网址 www.DedeCMS8.com 网站地图
  • 联系我们 1978130638@qq.com ,  QQ