volatile的使用

     这几天老是纠结于这个关键字,啃了些资料,稍微有点体会,就先写下来吧,要深入理解估计需要更深的汇编知识和编译原理方面的知识。

     1. 以下三个是常用到volatile的地方:

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

2) 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)
3) 多线程应用中被几个任务共享的变量

     2. volatile的精确定义及解释:

     volatile意为易变的,一个申明为volatile的变量即时告诉编译器这个变量是可以在意想不到的地方被改变,于是编译器就不会去假设这个变量的值,优化器在每次使用这个变量就不会使用保存在寄存器里的备份,而是直接从源地址读取这个变量的值。由上可知,申明为volatile的目的就是告诉编译器每次使用这个变量时都从变量的地址处取值,而这样做的原因是这个变量“可能会被意想不到地改变”。volatile解释为“直接存取原始内存地址”比较合适。

   3. “直接存取原始内存地址”

 一般思维下,我们总是假定程序中使用的变量即是我们定义的那个变量的地址的值,然而在有优化的情况下,实际并不一定是这样的。

       首先来看执行效率,编译器操作寄存器比操作内存要快得多。以下2组指令中,尽管第2组有3条指令,但执行时间依然比第一组更快:

1) inc jiffies ;  2) mov jiffies, %eax; inc %eax; mov %eax, jiffies

于是,出于执行效率的考虑,编译器将优化我们的代码。即,在本线程内,当读取一个变量时,为提高存取速度,编译器优化时有时会先把变量读取到一个寄存器中以后,再取变量值时,就直接从寄存器中取值;当变量值在本线程里改变时,会同时把变量的新值copy到该寄存器中,以便保持一致;例如:

 

以上代码,经过编译后将产生如下汇编代码:

 

若i申明为volatile变量,则汇编代码变为:

 

由上面的代码可以看出,当变量i申明为volatile时,每次使用i编译器都将从内存地址里读取i的值;在i不是volatile的情况下,编译器发现a = i; 和 b = i;之间没有对i进行过操作,即假定i的值没有变化,于是直接将寄存器的值赋给b.因此,使用volatile与否的关键在于a = i;和b = i;之间会不会发生使i改变的事件.

4. "意想不到的改变"

  通过3.可知,当一个变量可能被意想不到地改变时,则应该被申明为volatile型,那么,什么情况下变量会被意想不到地改变呢?通常的可能有三种:

1)  若变量为硬件状态寄存器,则外部硬件可能会改变变量的值;

2)  若在执行完a = i;之后发生中断,而中断服务程序中又使用并改变了i的值;

3)  若在执行到a = i;之后,本线程的时间片用完,调度程序调度新的线程执行,而新的线程又改变了i的值;

4)  若系统为多处理器,在一个处理器执行完a=i时,另一个处理器修改了i的值.

以上三种情况分别对应1的结论里的1),2),3)条。

 

 

volatile关键字主要用于确保多线程环境下共享变量的可见性和禁止指令重排序。当一个变量被volatile修饰时,每次访问该变量时都会从内存中读取最新的值,而不是使用寄存器中的备份。这样可以避免多线程环境下的数据不一致性问题。 使用volatile关键字的场景包括: 1. 多线程环境下的共享变量:当多个线程同时访问一个共享变量时,使用volatile关键字可以确保每个线程都能看到最新的值,避免数据不一致的问题。 2. 硬件寄存器的访问:在嵌入式开发中,对硬件寄存器的访问通常需要使用volatile修饰指针,以确保每次访问都能从内存中读取最新的值。 需要注意的是,volatile关键字无法保证操作的原子性,因此在需要保证原子性的操作时,仍然需要使用synchronized关键字或其他线程安全的机制。此外,使用volatile关键字也需要满足一定的条件,比如对变量的写操作不依赖于当前值,且该变量没有包含在具有其他变量的不变式中。 #### 引用[.reference_title] - *1* [volatile的用法](https://blog.youkuaiyun.com/qq_31452291/article/details/119239182)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [【002 关键字】一文彻底搞懂volatile用法](https://blog.youkuaiyun.com/qq_41709234/article/details/123028868)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值