C语言关键字volatile

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的值才是正确的值。