首页 新闻 会员 周边 捐助

多线程中若何对值类型加锁

0
悬赏园豆:5 [已解决问题] 解决于 2010-11-18 17:27

      monitor虽然可以给值类型加锁,但MSDN上说     

如果再次将相同的变量传递给 Enter,则它被装箱为一个单独对象,而且线程不会阻止。Monitor 本应保护的代码未受保护

  那就是说加了也白加

菜鸟吃虫,虫吃菜的主页 菜鸟吃虫,虫吃菜 | 初学一级 | 园豆:34
提问于:2010-11-17 11:00
< >
分享
最佳答案
0

值类型是不需要加锁的。因为没有线程安全问题,但是有逻辑问题。说说你的逻辑,然后再谈lock会好一点

收获园豆:2
沉默的糕点 | 小虾三级 |园豆:1786 | 2010-11-17 13:04
值类型不会有线程安全问题?开玩笑吧···
LittlePeng | 园豆:3445 (老鸟四级) | 2010-11-18 21:19
应该说对于unboxed的ValueType不需要关心同步问题。对于Int32,Bool等值类型,但是可以假设他们是线程安全,因为CLI保证了他们的是原子性,假设一个Int32变量 ,每次赋值,都会更新Int32的全部,而不是一部分。
沉默的糕点 | 园豆:1786 (小虾三级) | 2010-11-18 22:06
呃,多处理器时会有cpu缓存问题吧,不同核心是不共享缓存的,貌似都是volatite刷回,或者Interlocked 这种CAS 处理器级别原子实现。.Net还没有在语言的层面上做到同步
LittlePeng | 园豆:3445 (老鸟四级) | 2010-11-19 19:38
这个应该不是语言级别提供的,而是CLR 实现了该自动对齐。这是 CLI规范 12.6.6 "A conforming CLI shall guarantee that read and write access to properly aligned memory locations no larger than the native word size is atomic when all the write accesses to a location are the same size."
沉默的糕点 | 园豆:1786 (小虾三级) | 2010-11-19 23:22
我明白这个意思,就是说32位机器上4B读写时原子性的,64位机器则8B读写原子性。不过这里的原子性真的能做到线程安全吗?当然以前的单逻辑处理器肯定可以的。还有实际上对引用对象操作也不是4B指针操作,他不是原子的么。 现在需要解决的问题的多逻辑处理器问题:就是缓存同步问题,这个可以通过volatite或InterLocked低级别无锁处理。
LittlePeng | 园豆:3445 (老鸟四级) | 2010-11-20 19:15
这里可以说是CLI提供的是物理上一致性,但无法做到逻辑上一致性
LittlePeng | 园豆:3445 (老鸟四级) | 2010-11-20 19:17
对的,一次更新多个ValueType,那么就要lock一个Object了。
沉默的糕点 | 园豆:1786 (小虾三级) | 2010-11-21 13:40
一个也要···
LittlePeng | 园豆:3445 (老鸟四级) | 2010-11-21 17:13
真的吗?这个要开新帖讨论
沉默的糕点 | 园豆:1786 (小虾三级) | 2010-11-22 00:03
推荐看看这个CLR内存模型,虽然是2.0的,应该也没太大改动吧:) http://www.cnblogs.com/lucifer1982/archive/2008/03/16/1108456.html
LittlePeng | 园豆:3445 (老鸟四级) | 2010-11-23 23:58
其他回答(2)
0

我感觉加锁,指的是给一段代码加锁,就是设定一个临界区,在里面对临界资源进行操作。
.net里面的实现方式,如lock(object)这种简化写法,是定义了lock块为临界区。而作为参数的object在加锁/释放锁的操作中用到,而 其他线程在某一线程锁住object后 依旧可以访问object,可以调用object的方法(已测试,object被定义为static)。

所以我感觉,你要锁住某个值类型,就是在 lock块里面操作这个值类型即可。

另外,传给Enter 一个值类型,在解锁过程中会发生问题好像。

以上是我的理解,不对的化,大家指教

收获园豆:2
SoXLiang | 园豆:142 (初学一级) | 2010-11-17 11:46
0

lock是通过对象的SyncIndexblock实现的,也就是值类型没有进程同步块,是没法给lock的。

然而这里又可以lock,这是因为对值类型lock之后会有装箱操作。但是这个装箱操作对于每个线程每次进入都有一次装箱 操作,也就是每次锁定的对象都不同,那不就是白加啦:)

收获园豆:1
LittlePeng | 园豆:3445 (老鸟四级) | 2010-11-17 21:01
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册