1.简介
volatile关键字,作为一个指令关键字,确保本条指令不会因为编译器的优化而省略,且要求每次
直接读取值。该关键字可以保持内存可见性,但不是保证原子性(无法知道是否有其它线程在修改该地址的值)内存可见性,是保证每次都可以读取到最新值。
另外一个是保证有序性(这个只是保证这个变量之前的代码一定比它先执行,但是并不保证这个变量之前的代码不可以重排序)。
一个定义为volatile的变量就是说这个变量可能会意想不到的改变,这样编译器就不会去随便假设
这个变量的值,精确说,编译器优在用到这个变量的值的时候,必须每次都小心重新读取这个变量的值,而不是使用保存在寄存器里面的备份。
2.使用实例
在linux上进程操作时,我们可以使用一个经典的vfork来学习。vfork创建的子进程共享父进程, 我们使用一个value变量来测试。 非volatile的情况,编译器可能优化vaule的读取
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc , char ** argv)
{
pid_t pid;
int value = 0;
printf("-------file name : %s ----\r\n",__FILE__);
pid = vfork();
if(pid > 0)
{
while(1){
printf("This is father: %d \r\n",getpid());
printf("father : %d\r\n",value);
sleep(3);
}
} else if(pid ==0 )
{
while(1){
value ++;
printf("This is son: %d \r\n",getpid());
printf("son : %d\r\n",value);
sleep(3);
exit(0);
}
}
return 0;
}
测试结果
从上面看到虽然子进程修改了value的值,但是在父进程中该值的读取却是使用了寄存器值,导致了看到父进程
value=0.
将上述value修改成volatile变量,再次运行:
此时value的值才是正确的值。
您还没有登录,请您登录后发表评论。