close
口譯價格寫入 Volatile 物件稱為 Volatile 寫入。Volatile 寫入具有「釋放語意」;即包管 Volatile 寫入産生於任何記憶體進行參考以後,而任何記憶體參考則是依指令挨次産生在 Volatile 寫入之前。


在 此類型中,方式 Main 將啟動新的執行緒來履行方式 Thread2。此方式會將數值貯存到稱為 result 的非 Volatile 物件內,接著將 true 貯存於 finished 的 Volatile 物件內。主履行緒將守候物件 finished 設成 true後,再接著讀取物件 result。因為 finished 已宣告成 volatile,主履行緒必需從物件 result 中讀取數值 143翻譯若物件 finished 未宣佈成 volatile,主履行緒就可能在看到存至 finished 以後,才會看到貯存至 result,是以主履行緒會從物件 result 中讀到數值 0。將 finished 宣告成 volatile 物件可以避免這類紛歧致的狀態産生。


Volatile這玩意兒用在單晶片的C說話較多
例如:Volatile char wait;

void xxx(void)
{
wait=1;
while (wait!=0);
.....
.....
}
void timer0(void) interrupt 1
{
wait=0;
.......
}


xxx()中就是等一個timer中斷才執底下工作.
假如不寫Volatile會被編譯器省略掉.
因為wait=1;何來wait會等於0


"volatile"是一個樞紐字(keyword),用來潤飾詞資料型態,與const有對應的關係。
是說話關鍵字的話,就不會泛起在標頭檔內的界說。
"volatile sig_atomic_t read_flag = 1;"
read_flag是一個為sig_atomic_t的資料型態,透過volatile的潤色,申明sig_atomic_t在程式中,可以在任何的時候下被個別的 thread 所點竄
也就是說,翻譯公司的程式可能統一時間不止一個程序在利用。
可能主程式main在利用的同時,I/O Device或另外一個thread也在哄騙或指定這個read_flag 來透過溝通的感化翻譯


【"關於volatile要害字的說明和測試"】

volatile環節字是一種類型潤色符,用它宣佈的類型變數示意可以被某些編譯器未知的身分更改,比如:功課系統、硬體或其他履行緒等。碰到這個要害字宣佈的變數,編譯器對存取該變數的程式碼就不再進行最佳化,從而可以供應對特殊位址的不亂存取。

利用該關頭字的例子如下:

讀取 Volatile 物件稱為 Volatile 讀取翻譯Volatile 讀取具有「獲得語意」;即包管 Volatile 讀取會産生在任何對記憶體進行參考之前,而任何參考是依指令遞次産生在 Volatile 讀取以後。
int b = i;


【C說話內"volatile"的用法和功用】

volatile int i=10;
int a = i;

printf("i= dn",a);


The compilation system tries to reduce code size and execution time on all machines翻譯社 by optimizing code. It is programmer responsibility to inform compilation system that certain code (or variable) should not be optimized. Many programmers do not understand when to use volatile to inform compilation system that certain code should not be optimized or what it does. Although (no doubt) their program work, they do not exploit the full power of the language.

A variable should be declared volatile whenever its value can be changed by something beyond the control of the program in which it appears, such as a concurrently executing thread. Volatile, can appear only once in a declaration with any type specifier; however, they cannot appear after the first comma in a multiple item declaration. For example, the following declarations are legal

何謂callback function?
More ways to map memory
volatile int p = 3;

declares and initializes an object with type volatile int whose value will be always read from memory.

Volatile T a =3;
T volatile a=3;

The declaration declares and initializes an objet with type volatile T whose value will be always read from memory

T* volatile ptrv;

Use of volatile

- An object that is a memory-mapped I/O port
- An object variable that is shared between multiple concurrent processes
- An object that is modified by an interrupt service routine
- An automatic object declared in a function that calls setjmp and whose value is-changed between the call to setjmp and a corresponding call to longjmp

Conclusion

*ptr = 0;
while(*ptr){
*ptr = 4 ;
*ptr = 0 ;
}
the above code may be optimize as
*ptr = 0
while(0) {
}

*ptr is assigned 0 before value 4 is used ( and value of *ptr never changes ( same constant is always assigned to it)
volatile keyword is used to suppress these optimization the compiler assumes that the value can change any time 翻譯社 even if no explicit code modify it to suppress all optimization declare ptr as

 volatile char * const ptr = (volatile char*)0x16

this declaration say the object at which ptr points can change without notice , but that ptr itself is a constant whose value never change

/listing 3: difference between listing 1 and listing 3 ***/

< .file"vol.c"
---
> .file"wvol.c"
< movl$3翻譯社 -4(%ebp)
< movl-4(%ebp)翻譯社 %eax
< pushl%eax
> pushl$3
< movl$5翻譯社 -4(%ebp) / * store in stack */


From above listing 3 it is clear that when you use setjmp and longjmp, the only automatic variables guaranteed to remain valid are those declared volatile.

/*Listing1: Assembly code fragment of above program
Produced by cc compiler when volatile is used*/



.file"vol.c"
main:
pushl%ebp
movl%esp, %ebp
subl$20翻譯社 %esp
movl$3, -4(%ebp)
pushl$buf
call_setjmp
addl$16, %esp
testl%eax, %eax
je.L18
subl$8, %esp
movl-4(%ebp), %eax
pushl%eax
pushl$.LC0
callprintf
movl$0, (%esp)
callexit
.p2align 2
.L18:
movl$5, -4(%ebp)
subl$8, %esp
pushl$1
pushl$buf
calllongjmp


#include <thread.h>
#include <stdio.h>
volatile int num ;

void* foo()
{
while(1) {
++num ;
sleep(1000);
}
}

main()
{
int p ;
void *targ =NULL ;
thread_t id ;
num = 0;
p = thr_create((void*)NULL 翻譯社 0,foo,targ,0,&id);
if(!p) printf(" can not create thread ");

while(1)
{
printf("%d" , num ) ;
}
}

the compiler may use a register to store the num variable in the main thread , so the change to the value by the second thread are ignored . The volatile modifier is a away of telling the compiler that no optimization applied to the variable its value be not placed in register and value may change outside influence during evaluation

# An automatic object declared in a function that calls setjmp and whose value is-changed between the call to setjmp and a corresponding call to longjmp

Variables local to functions that call setjmp is most often used. When an automatic object is declared in a function that calls setjmp, the compilation system knows that it has to produce code that exactly matches what the programmer wrote. Therefore, the most recent value for such an automatic object will always be in memory (not just in a register) and as such will be guaranteed to be up-to-date when longjmp is called. Without volatile variable is undefined by the standard whether the result one see differs with or without optimization simply reflects that fact Consider following code

 /*Listing 2:Assemply code fragment of  above program
produced by cc compile witout volatile keword */

.file"wvol.c"
main:
pushl%ebp
movl%esp翻譯社 %ebp
subl$20翻譯社 %esp
pushl$buf
call_setjmp
addl$16, %esp
testl%eax, %eax
je.L18
subl$8, %esp
pushl$3
pushl$.LC0
callprintf
movl$0, (%esp)
callexit
.p2align 2
.L18:
subl$8翻譯社 %esp
pushl$1
pushl$buf
calllongjmp


char const ptr=(char*)0X15 ;

*ptr access the port consider following code fragment to set the third bit of the output port at periodic intervals

About the author

T i翻譯社 volatile vi ;

Volatile qualifiers can be used to change the behavior of a type. For example,

C語言相關切磋,細究指標(pointer)與參照(reference)

}

分別在偵錯版本和release版本運行程式,輸出都是:

i = 10
i = 32

這申明這個樞紐字發揮了它的感化!


Place volatile accurately
int b = i;
printf("i= dn",b);
Qualifiers in multilevel pointers


  volatile 指 出 i是隨時可能産生變化的,每次利用它的時候必需從i的位址中讀取,因而編譯器生成的組合說話程式碼會從新從i的位址讀取資料放在b中翻譯而最好化做法是,由 於編譯器發現兩次從i讀數據的程式碼之間的程式碼沒有對i進行過操作,它會自動把前次讀的資料放在b中。而不是重新從i裡面讀。如許以來,若是i是一個寄 存器變數或者默示一個埠資料就輕易出錯,所以說volatile可以保證對非凡位址的不亂存取。
  注意,在vc6中,一般偵錯模式沒有進行程式碼最好化,所以這個環節字的感化看不出來翻譯下面經由過程插入組合語言程式碼,測試有沒有volatile關頭字,對程式終究程式碼的影響:
  
  起首,用classwizard建一個win32 console專案,插入一個voltest.cpp檔,輸入下面的程式碼:
 
#include <stdio.h>
void main()
{

...
//其他代碼,並未明確告知編譯器,對i進行過操作

int volatile nVint;
result = 143

# An object that is a memory-mapped I/O port

Volatile T * ptr; 
T volatile * ptr;

Ptr is a a pointer to a volatile T:

static lon int  num ;
void interrupt update(void)
{
++num ;
}
main()
{
long val ;
val = num ;
while(val !=num)
val = num ;
rturn val ;
}

When compilation system execute while statement, the optimizer in compiler may notice that it read the value num once already and that value is still in the register. Instead of re reading the value from memory, compiler may produce code to use the (possibly messed up) value in the register defeating purpose of original C program. Some compiler may optimize entire while loop assuming that since the value of num was just assigned to val , the two must be equal and condition in while statement will therefore always be false .To avoid this 翻譯社you have to declare num to be volatile that warns compilers that certain variables may change because of interrupt routines.

Syntax

When using exact semantics is necessary, volatile should be used. If you are given a piece of touchy code given as above. It is a good idea in any case to look the compiler outputting listing at the assembly language to be sure that compiler produce code that makes sense.

Use of volatile

C++基本功:全面把握const、volatile和mutable樞紐字

}

然後,在偵錯版本模式運行程式,輸出結果以下:
i = 10
i = 32
然後,在release版本模式運行程式,輸出後果以下:
i = 10
i = 10
輸出的結果明明評釋,release模式下,編譯器對程式碼進行了最佳化,第二次沒有輸出准確的 i 值。下面,天成翻譯公司們把 i的宣佈加上volatile關鍵字,看看有什麼轉變:

#include <stdio.h>
void main()
{

Mapping memory

}

"Right-Left" Rule

}

Console.WriteLine("result = {0}"翻譯社 result);
return;

當物件宣佈包括 volatile 潤色詞時,宣佈所引入的物件為 Volatile 物件翻譯

if (finished) {


 }

參考型別翻譯

 result = 143;
finished = true;

型別 byte、sbyte、short、ushort、int、uint、char、float 或 bool。
具有羅列基底型別 byte、sbyte、short、ushort、int 或 uint 的羅列型別翻譯

public static int result;
public static volatile bool finished;
static void Thread2() {


以下類型

}

會產生以下輸出:


這些限制可確保所有的履行緒,將可以或許視察到任何其他履行緒都依其執行遞次履行 Volatile 寫入。遵循此限制的實作其實不需要供應單一整體的 Volatile 寫入遞次,就如同履行的所有履行緒所見。Volatile 物件的型別必需為以下之一:

對 於非 Volatile 物件,從新分列指令的最好化技能,可能會在多重履行緒的程式中致使未預期與沒法預感的了局,因為這類程式沒法利用如 lock 陳說式所供應的同步化來存取物件。這些最好化可由編譯器、Runtime 系統或硬體來履行翻譯對於 Volatile 物件,這類從新分列最好化有以下限制:
//下面組合說話語法的作用就是改變記憶體中i的值,然則又不讓編譯器知道
__asm {
mov dword ptr [ebp-4], 20h
}

Keyword volatile can be placed before or after the data type in the variable definition. For example following declaration are identical:

指標函數和函數指標有什麼區別

Pointer declaration

volatile pointer to a volatile variable  
int volatile * volatile ptr;

volatile can be applied to derived types such as an array type 翻譯社in that case翻譯社 the element is qualified翻譯社 not the array type. When applied to struct types entire contents of the struct become volatile. You can apply the volatile qualifier to the individual members of the struct. Type qualifiers are relevant only when accessing identifiers as l-values in expressions. volatile does not affects the range of values or arithmetic properties of the object.. To declare the item pointed to by the pointer as volatile翻譯社 use a declaration of the form:

C 說話指標的用法
volatile T *vptr;



To declare the value of the pointer - that is, the actual address stored in the pointer - as volatile, use a declaration of the form:

正確利用const / 關頭字Const 與Volatile的利用
static volatile  long int num ;

With volatile keyword in the declaration the compiler knows that the value of num must b read from memory every time it is referenced.

an 8 bit 翻譯社 memory -mapped I/O port at physical address 0X15 can be declared as

Interrupt service routines often set variables that are tested in main line code. One problem that arises as soon as you use interrupt is that interrupt routines need to communicate with rest of the code .A interrupt may update a variable num that is used in main line of code .An incorrect implementation of this might be:

# An object modified by an interrupt service routine

/* Let T denotes some data type */
typedef volatile T i;
volatile T i;
T volatile i ;

And the following declaration is illegal

#include <setjmp.h>
static jmp_buf buf ;
main( )
{
volatile int b;
b =3 ;
if(setjmp(buf)!=0) {
printf("%d ", b) ;
exit(0);
}
b=5;
longjmp(buf 翻譯社 1) ;
}

volatile variable isn't affected by the optimization. So value of b is after the longjump is the last value variable assigned. Without volatile b may or may not be restored to its last value when the longjmp occurs. For clear understanding assembly listing of above program by cc compiler has been given below.

# An object that is shared between multiple concurrent processes

if two threads/tasks concurrently assign distinct values to the same shared non-volatile variable, a subsequent use of that variable may obtain a value that is not equal to either of the assigned values翻譯社 but some implementation-dependent mixture of the two values. so a global variable references by multiple thread programmers must declare shared variable as volatile.

__asm {
mov dword ptr [ebp-4], 20h
}

int b = i;
printf("i= dn",b);

  當要求使用volatile 宣佈的變數的值的時辰,系統總是從新從它地點的記憶體讀取資料,即使它前面的指令方才從該處讀取過資料翻譯而且讀取的資料馬上被保留。

例如:

int i=10;
int a = i;

printf("i= dn",a);

using System;
using System.Threading;
class Test
{
  

}

static void Main() {

volatile int i=10;
int a = i;

finished = false;
// Run Thread2() in a new thread
new Thread(new ThreadStart(Thread2)).Start();
// Wait for Thread2 to signal that it has a result by setting
// finished to true.
for (;;) {


Volatile as a promise

Ashok K. Pathak a member ( Research Staff ) at Bharat Electronics Limited (CRL) , Ghaziabad .He has been developing embedded application for the past five years. Ashok holds a M.E in computer science and engineering . Ashok recently completed a book about' "Advanced Test in C and Embedded System Programming" , Published by BPB 翻譯社 ND .He can be reached at pathak@indiya.com.


延長浏覽:





以下內文出自: http://bluelove1968.pixnet.net/blog/post/222282820-%e3%80%90c-%e8%aa%9e%e8%a8%80%e5%85%a7%22volatile
有關各國語文翻譯公證的問題歡迎諮詢天成翻譯公司02-77260931
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 vickieg11m1 的頭像
    vickieg11m1

    waynepearlep