Randy
人之所以痛苦,在于追求错误的东西
volatile
尽管C和C++标准对于线程都明显的“保持沉默”,但它们以volatile关键字的形式,确实为多线程保留了一点特权。
就象大家更熟悉的const一样,volatile是一个类型修饰符(type modifier)。
它是被设计用来修饰被不同线程访问和修改的变量。
如果没有volatile,基本上会导致这样的结果:要么无法编写多线程程序,要么编译器失去大量优化的机会。
class
Gadget
{
public
:
void
Wait()
{
while
(
!
flag_)
{
Sleep(
1000
);
//
sleeps for 1000 milliseconds
}
}
void
Wakeup()
{
flag_
=
true
;
}
private
:
bool
flag_;
}
;
上面代码中Gadget::Wait的目的是每过一秒钟去检查一下flag_成员变量,当flag_被另一个线程设为true时,该函数才会返回。
然而,这个Wait函数是错误的。
假设编译器发现Sleep(1000)是调用一个外部的库函数,它不会改变成员变量flag_,那么编译器就可以断定它可以把flag_缓存在寄存器中,以后可以访问该寄存器来代替访问较慢的主板上的内存。
这对于单线程代码来说是一个很好的优化,但是在现在这种情况下,
它破坏了程序的正确性:当你调用了某个Gadget的Wait函数后,即使另一个线程调用了Wakeup,Wait还是会一直循环下去。
这是因为flag_的改变没有反映到缓存它的寄存器中去。编译器的优化未免有点太……乐观了。
在大多数情况下,把变量缓存在寄存器中是一个非常有价值的优化方法,如果不用的话很可惜。
C和C++给你提供了显式禁用这种缓存优化的机会。如果你声明变量是使用了volatile修饰符,
编译器就不会把这个变量缓存在寄存器里——每次访问都将去存取变量在内存中的实际位置。
这样你要对Gadget的Wait/Wakeup做的修改就是给flag_加上正确的修饰:
class
Gadget
{
public
:
private
:
volatile
bool
flag_;
}
;
posted on 2008-10-13 17:27
Randy
阅读(156)
评论(0)
编辑
收藏
引用
只有注册用户
登录
后才能发表评论。
【推荐】100%开源!大型工业跨平台软件C++源码提供,建模,组态!
网站导航:
博客园
IT新闻
BlogJava
知识库
博问
管理
Powered by:
C++博客
Copyright © Randy
<
2007年10月
>
日
一
二
三
四
五
六
30
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
5
6
7
8
9
10
导航
C++博客
首页
新随笔
联系
聚合
管理
统计
随笔 - 37
文章 - 0
评论 - 24
引用 - 0
常用链接
我的随笔
我的评论
我参与的随笔
留言簿
(3)
给我留言
查看公开留言
查看私人留言
随笔档案
2009年11月 (1)
2009年6月 (1)
2009年5月 (3)
2009年3月 (2)
2008年12月 (1)
2008年11月 (3)
2008年10月 (4)
2008年9月 (1)
2008年7月 (3)
2008年6月 (1)
2008年4月 (1)
2008年3月 (3)
2008年2月 (2)
2007年11月 (2)
2007年10月 (9)
搜索
最新评论
1. re: richedit2
我想知道SendMessage(hwndBuffer, EM_SETSEL,lparam,wparam);中lparam和wparam的含义。。。求告知
--gook
2. re: c++之父之一席之谈(也许是笑话,但不要仅仅当成笑话)[未登录]
可以再无知一点么
--哈哈
3. re: C++ 枚举类型的思考[未登录]
operator int()还是需要的
支持
这个很需要的
现在C++11 出来了,域的问题解决了
但还是需要 operator int()
--kk
4. re: 毫秒级计时器
国外新闻
http://www.ciqol.net/seenews
--外贸领航
5. re: C++ 枚举类型的思考[未登录]
评论内容较长,点击标题查看
--K
阅读排行榜
1. C++ 枚举类型的思考(6302)
2. 毫秒级计时器(5465)
3. C++界面库 - Xtreme Toolkit Pro[转载](3339)
4. 在控制台程序中隐藏控制台窗口(2589)
5. Google单元测试框架(转)(2315)
评论排行榜
1. 内存填充值的理解(8)
2. C++ 枚举类型的思考(7)
3. c++之父之一席之谈(也许是笑话,但不要仅仅当成笑话)(2)
4. 字节对齐(2)
5. C/C++中的近指令、远指针和巨指针(1)