免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: Aquester
打印 上一主题 下一主题

[C] 一个线程对long类型变量进行修改,多个线程只读这个long类型值,需要加锁吗? [复制链接]

论坛徽章:
0
11 [报告]
发表于 2008-12-17 22:32 |只看该作者
需要。

论坛徽章:
0
12 [报告]
发表于 2008-12-17 22:33 |只看该作者

回复 #10 Aquester 的帖子

有区别吗?不同样在改变一个全局变量吗?
至少也要3条汇编代码的吧

论坛徽章:
0
13 [报告]
发表于 2008-12-17 22:35 |只看该作者
If a double or long variable is not declared volatile, then for the purposes of load, store, read, and write operations it is treated as if it were two variables of 32 bits each; wherever the rules require one of these operations, two such operations are performed, one for each 32-bit half. The manner in which the 64 bits of a double or long variable are encoded into two 32-bit quantities and the order of the operations on the halves of the variables are not defined by The Java  Language Specification.

This matters only because a read or write of a double or long variable may be handled by an actual main memory as two 32-bit read or write operations that may be separated in time, with other operations coming between them. Consequently, if two threads concurrently assign distinct values to the same shared non-volatile double or long variable, a subsequent use of that variable may obtain a value that is not equal to either of the assigned values, but rather some implementation-dependent mixture of the two values.

An implementation is free to implement load, store, read, and write operations for double and long values as atomic 64-bit operations; in fact, this is strongly encouraged. The model divides them into 32-bit halves for the sake of currently popular microprocessors that fail to provide efficient atomic memory transactions on 64-bit quantities. It would have been simpler for the Java virtual machine to define all memory transactions on single variables as atomic; this more complex definition is a pragmatic concession to current hardware practice. In the future this concession may be eliminated. Meanwhile, programmers are cautioned to explicitly synchronize access to shared double and long variables.

“深入java虚拟机”提到int等不大于32位的类型上的操作都是原子操作

论坛徽章:
0
14 [报告]
发表于 2008-12-17 22:37 |只看该作者
我认为只需要对写加锁就行了
读不用

论坛徽章:
0
15 [报告]
发表于 2008-12-17 22:39 |只看该作者

回复 #13 Aquester 的帖子

那也只是在一些平台上
前面不有人说了吗,有时候正确,有时候会乱套

论坛徽章:
0
16 [报告]
发表于 2008-12-17 22:41 |只看该作者
32位long赋值操作是原子的。++,-- 不是。
不加锁,读出的有可能是乱了数值。

论坛徽章:
0
17 [报告]
发表于 2008-12-17 22:51 |只看该作者
对程序逻辑来说,需要加锁,
从指令层来说,凡是 load-execution-store 类指令都要加锁

论坛徽章:
0
18 [报告]
发表于 2008-12-17 22:58 |只看该作者
C语言赋值语句不是原子操作
单单从硬件的角度来看赋值是非原子的,但是却忘记了应用程序是运行在内核之上的,很多的同步是由内核来完成的

在Linux Kernel Development(2nd)的进程管理一章中找到一下这句话.
On modern operating systems, processes provide two virtualizations: a virtualized processor and virtual memory. The virtual processor gives the process the illusion that it alone monopolizes the system, despite possibly sharing the processor among dozens of other processes. Chapter 4, "Process Scheduling," discusses this virtualization. Virtual memory lets the process allocate and manage memory as if it alone owned all the memory in the system. Virtual memory is covered in Chapter 11, "Memory Management." Interestingly, note that threads share the virtual memory abstraction while each receives its own virtualized processor.

对于应用程序来说,所有内存操作和寄存器操作都是在虚拟的(由内核来管理),也就是上面提到的虚拟内存和虚拟处理器.
对于多线程的程序来讲它们是共享虚拟内存,但是并不共享虚拟处理器(当然包括寄存器).
所以对多线程的程序原子操作只要关心内存操作是否为原子的,而并不需要关心寄存器.
因为Kernel在进行进程和线程调度的时候都会保护现场.

如果有不对之处请大家纠正,补充

论坛徽章:
0
19 [报告]
发表于 2008-12-17 23:23 |只看该作者
原帖由 FuriousFive 于 2008-12-17 22:37 发表
我认为只需要对写加锁就行了
读不用

你没明白锁是啥样的。。

论坛徽章:
0
20 [报告]
发表于 2008-12-18 00:19 |只看该作者
原帖由 Aquester 于 2008-12-17 22:58 发表
C语言赋值语句不是原子操作
单单从硬件的角度来看赋值是非原子的,但是却忘记了应用程序是运行在内核之上的,很多的同步是由内核来完成的

在Linux Kernel Development(2nd)的进程管理一章中找到一下这句话.
...


对赋值语句来说是原子的。就算对于C语句来说也是原子的
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP