volatile--眼见为实

The volatile keyword was devised to prevent compiler optimizations that might render code incorrect in the presence of certain asynchronous events.


以前看过volatile的解释,但实际上事情是怎么发生的,心里还是没底。俗话说,眼见为实,要实验证实一下,就要看生成的汇编代码是什么样子的。我用的是VC6,下面是具体的实验步骤:
写一个文件,比如:testvolatile.cpp,内容如下:

void dosomething(){
}

void thread1( int& status)
{
    status = 1;   

    if(status>0){
        dosomething();
    }
}
void thread2(int& status )
{
    status = 0;
}

放在一个工程里,选择Relase版,打开工程设置,在C/C++标签里, 选择Category:Optimizations,选择Maximize Speed, 再选择Category:Listring Files,把Listing file type: 设成Assembly-Only Listing (于是可以生成asm文件,当然选择Assembly with code也可以)。
为什么不用Debug版?因为Debug版不会做代码优化,也就看不出问题。


设置好了,编译testvolatile.cpp,在./Release目录里生成了:testvolatile.asm文件。用文本方式打开,可以看到后面的内容:
...
; Line 6
    mov    eax, DWORD PTR _status$[esp-4]
    mov    DWORD PTR [eax], 1
; Line 9
    jmp    ?dosomething@@YAXXZ            ;

dosomething
?thread1@@YAXAAH@Z ENDP                    ;
...
可以看到,dosomething()是无条件被执行的,不管status是多少。

现在把thread1的输入参数改成volatile:
void thread1( volatile int& status)
重新编译,打开汇编文件,看到:
; Line 6
    mov    eax, DWORD PTR _status$[esp-4]
    mov    DWORD PTR [eax], 1
; Line 8
    mov    ecx, DWORD PTR [eax]
    test    ecx, ecx
    jle    SHORT $L270
; Line 9
    jmp    ?dosomething@@YAXXZ            ;

dosomething
$L270:
; Line 11
    ret    0
?thread1@@YAXACH@Z ENDP                    ;
...
这里如代码所希望的,根据变量status的值来选择是否要调用dosomething()。
比较这两个汇编文件,发现编译器会根据变量值来优化条件语句,在多线程下需要考虑volatile的使用。

testvolatile.cpp的意思是:
thread1() 和thread2()可能被不同线程调用,thread1里可能会做一些别的工作,然后才走到if(status>0)语句,根据status当前值来选择是否dosomething();这其实是两个线程根据status来同步工作。

P.S., volatile 和mutex的用途有所不同。mutex可以用来保证线程函数的同步,比如在thread1()或其他函数里加mutex锁,可以让多线程进入这些函数时串行等待。而这里的status是为了让多个线程能够同时工作,然后在一定阶段进行同步的判断和处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值