色偷偷偷久久伊人大杳蕉,色爽交视频免费观看,欧美扒开腿做爽爽爽a片,欧美孕交alscan巨交xxx,日日碰狠狠躁久久躁蜜桃

volatile在多線程中的應(yīng)用

發(fā)布時間:2010-8-9 11:04    發(fā)布者:lavida
關(guān)鍵詞: volatile , 多線程
volatile在詞典中的意思是易變的,反復(fù)無常的。它在我們的程序設(shè)計中常常用到的。volatile是一個關(guān)鍵字,用來修飾一個變量,告訴編譯器在編譯的時候不要對其進(jìn)行優(yōu)化,在操作寄存器和多線程中這種用法是最常見的。  

有這樣一個例子:  

#include   
#include   
void my_func();  
int? i;  
int main()  
{  
pthread_t my_thread;  
int err,k;  
if ((err = pthread_create(&my_thread,NULL,(void *)my_func,NULL))   
perror("can't create thread:%s\n");  
i = 2;  
while(i == 2);  
printf("main:%d\n",i);  
while(1);  
return 0;?  
}  
void my_func()  
{  
sleep(1);  
i = 3;  
printf("my_func:%d\n",i);  
}  

這個例子本意是想讓主程序進(jìn)入while(i == 2)這個循環(huán),直到線程中將這變量i的值修改后跳出循環(huán),可是結(jié)果是  
my_func:3  
這與想像中的結(jié)果完全不一樣,是什么原因造成這樣的結(jié)果呢?查看一下匯編代碼,才知道,是編譯器將這段代碼給優(yōu)化掉了,匯編代碼如下:  

.file "test.c"  
.section .rodata.str1.1,"aMS",@progbits,1  
.LC0:  
.string "my_func:%d\n"  
.text  
.p2align 4,,15  
.globl my_func  
.type my_func, @function  
my_func:  
pushl %ebp  
movl %esp, %ebp  
subl $8, %esp  
movl $1, (%esp)  
call sleep  
movl $3, 4(%esp)  
movl $.LC0, (%esp)  
movl $3, i  
call printf  
leave  
ret  
.size my_func, .-my_func  
.section .rodata.str1.1  
.LC1:  
.string "can't create thread:%s\n"  
.text  
.p2align 4,,15  
.globl main  
.type main, @function  
main:  
leal 4(%esp), %ecx  
andl $-16, %esp  
pushl -4(%ecx)  
pushl %ebp  
movl %esp, %ebp  
pushl %ecx  
subl $36, %esp  
leal -8(%ebp), %eax  
movl $0, 12(%esp)  
movl $my_func, 8(%esp)  
movl $0, 4(%esp)  
movl %eax, (%esp)  
call pthread_create  
testl %eax, %eax  
js .L9  
.L4:  
movl $2, i  
.L6:  
jmp .L6  
.L9:  
movl $.LC1, (%esp)  
call perror  
jmp .L4  
.size main, .-main  
.comm i,4,4  
.ident "GCC: (GNU) 4.1.3 20080623 (prerelease) (Ubuntu 4.1.2-23ubuntu3)"  
.section .note.GNU-stack,"",@progbits  

在定義變量i的時候添加上volatile后:  
int volatile i;  
的結(jié)果為:  
my_func:3  
main:3  

這個結(jié)果顯然達(dá)到了我們預(yù)期的效果,再查看一下他的匯編代碼,會看到那個帶有條件的循環(huán)語句。  

.file "test.c"  
.section .rodata.str1.1,"aMS",@progbits,1  
.LC0:  
.string "my_func:%d\n"  
.text  
.p2align 4,,15  
.globl my_func  
.type my_func, @function  
my_func:  
pushl %ebp  
movl %esp, %ebp  
subl $8, %esp  
movl $1, (%esp)  
call sleep  
movl $3, i  
movl i, %eax  
movl $.LC0, (%esp)  
movl %eax, 4(%esp)  
call printf  
leave  
ret  
.size my_func, .-my_func  
.section .rodata.str1.1  
.LC1:  
.string "can't create thread:%s\n"  
.LC2:  
.string "main:%d\n"  
.text  
.p2align 4,,15  
.globl main  
.type main, @function  
main:  
leal 4(%esp), %ecx  
andl $-16, %esp  
pushl -4(%ecx)  
pushl %ebp  
movl %esp, %ebp  
pushl %ecx  
subl $36, %esp  
leal -8(%ebp), %eax  
movl $0, 12(%esp)  
movl $my_func, 8(%esp)  
movl $0, 4(%esp)  
movl %eax, (%esp)  
call pthread_create  
testl %eax, %eax  
js .L13  
.L4:  
movl $2, i  
.L6:  
movl i, %eax  
cmpl $2, %eax  
je .L6  
mov i, %eax  
movl $.LC2, (%esp)  
movl %eax, 4(%esp)  
call printf  
.L8:  
jmp .L8  
.L13:  
movl $.LC1, (%esp)  
call perror  
.p2align 4,,3  
jmp .L4  
.size main, .-main  
.comm i,4,4  
.ident "GCC: (GNU) 4.1.3 20080623 (prerelease) (Ubuntu 4.1.2-23ubuntu3)"  
.section .note.GNU-stack,"",@progbits  

比較紅色部分就會看到是什么造成這種差異了!  

為什么加上volatile和不加就有這么大的差距的,原因是每次使用變量都去內(nèi)存中取值,然后通過系統(tǒng)總線傳到CPU處理,會增加很大的開銷,所以在CPU的cache中位變量啊做了一個副本,通過這個副本來進(jìn)行賦值。在程序中首先對i 進(jìn)行復(fù)制“i = 2”,然后又將i和2進(jìn)行比較“i == 2”編譯器認(rèn)為i的值是2,沒有變化,認(rèn)為這個比較沒有意義就將其優(yōu)化掉了,將程序陷入無條件的死循環(huán)中,在線程my_func中修改i 的值夜就沒有意義了,最終結(jié)果就是我么看到了那樣了,加上volatile編譯器就不會優(yōu)化了,每次都被迫去內(nèi)存中去取值,達(dá)到了我們預(yù)期的結(jié)果。
本文地址:http://m.54549.cn/thread-20227-1-1.html     【打印本頁】

本站部分文章為轉(zhuǎn)載或網(wǎng)友發(fā)布,目的在于傳遞和分享信息,并不代表本網(wǎng)贊同其觀點和對其真實性負(fù)責(zé);文章版權(quán)歸原作者及原出處所有,如涉及作品內(nèi)容、版權(quán)和其它問題,我們將根據(jù)著作權(quán)人的要求,第一時間更正或刪除。
您需要登錄后才可以發(fā)表評論 登錄 | 立即注冊

關(guān)于我們  -  服務(wù)條款  -  使用指南  -  站點地圖  -  友情鏈接  -  聯(lián)系我們
電子工程網(wǎng) © 版權(quán)所有   京ICP備16069177號 | 京公網(wǎng)安備11010502021702
快速回復(fù) 返回頂部 返回列表