关键字volatile的含意

本文详细解析了C/C++中volatile关键字的意义及其应用场景,并通过具体实例展示了如何正确使用此关键字避免潜在的编程陷阱。

关键字volatile有什么含意并给出三个不同的例子。

答:一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子:

1). 并行设备的硬件寄存器(如:状态寄存器)

2). 一个中断服务子程序中会访问到的非自动变量(Non-automaticvariables)

3). 多线程应用中被几个任务共享的变量

回答不出这个问题的人是不会被雇佣的。我认为这是区分C程序员和嵌入式系统程序员的最基本的问题。嵌入式系统程序员经常同硬件、中断、RTOS等等打交道,所用这些都要求volatile变量。不懂得volatile内容将会带来灾难。

假设被面试者正确地回答了这是问题(嗯,怀疑这否会是这样),我将稍微深究一下,看一下这家伙是不是直正懂得volatile完全的重要性。

1). 一个参数既可以是const还可以是volatile吗?解释为什么。

2). 一个指针可以是volatile 吗?解释为什么。

3). 下面的函数有什么错误:

int square(volatile int *ptr)

{

return *ptr * *ptr;

}

下面是答案:

1). 是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。

2). 是的。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。

3). 这段代码的有个恶作剧。这段代码的目的是用来返指针*ptr指向值的平方,但是,由于*ptr指向一个volatile型参数,编译器将产生类似下面的代码:

int square(volatile int *ptr)

{

int a,b;

a = *ptr;

b = *ptr;

return a * b;

}

由于*ptr的值可能被意想不到地该变,因此a和b可能是不同的。结果,这段代码可能返不是你所期望的平方值!正确的代码如下:

long square(volatile int *ptr)

{

int a;

a = *ptr;

return a * a;

}

### Java `volatile` 关键字的作用 在多线程环境中,Java 的 `volatile` 关键字用于确保变量的修改能够立即对所有线程可见。这意味着任何线程对该变量的操作都会直接写入主内存,并且每次读取该变量时也会从主内存中获取最新值[^1]。 #### 可见性保障 通常情况下,每个线程拥有自己独立的工作内存副本,这可能导致某些线程看不到其他线程对共享数据所做的更改。通过使用 `volatile` 修饰符,则可以强制使这些更新立刻反映到主存储器上,从而让所有的线程都能看到最新的变化[^4]。 #### 防止指令重排序 除了提供可见性的保证外,`volatile` 还具有防止编译器优化带来的指令重排特性。即 JVM 不会对两个访问同一个 `volatile` 字段的操作进行重新排列顺序,这对于维护程序逻辑的一致性非常重要[^2]。 然而需要注意的是,虽然 `volatile` 提供了一定程度上的同步功能,但它并不能替代锁机制(如 `synchronized`),特别是在涉及复合动作的情况下——比如先检查再设置某个标志位这样的操作序列就不是原子性的;此时应该考虑采用更高级别的并发控制手段,像显式的锁定或是利用 java.util.concurrent 包下的工具类[^3]。 ```java public class VolatileExample { private volatile boolean isRunning = true; public void stop() { this.isRunning = false; } public void doWork() { while (isRunning) { // 执行一些任务... } } } ``` 在这个例子中,假设有一个后台线程正在运行 `doWork()` 方法里的循环体,而另一个前台线程调用了 `stop()` 来终止它。如果没有声明 `isRunning` 为 `volatile` 类型的话,那么即使后者成功设置了 `false` 值,前者也可能由于缓存原因继续无限期地执行下去。但是有了 `volatile` 后就能确保及时感知到状态的变化并停止工作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值