C語言中volatile關鍵字的使用

2021-01-07 電子發燒友
打開APP
C語言中volatile關鍵字的使用

發表於 2018-03-17 11:55:00

volatile的意思是易變的、可變的,作用是限制編譯器優化某些變量。首先看一段C51程序:

Keil在優化級別是為8時得到如下彙編代碼(部分未列出):

可以看到,變量d的值賦給x,y,z時,只有x中是直接讀取的d中數值,而y=d,z=d則直接將寄存器中的數值賦給y,z。若在此過程中,變量d的值被改變(比如d是一個硬體寄存器),則y,z變量中得到的數據將是錯誤的,因此在某些應用中程序存在隱患。

這類問題並不是編譯器的問題。由於訪問內部寄存器比訪問RAM速度塊,因此編譯器在編譯類似程序時,會對程序進行優化,除第一次編譯變量所在在連續讀取一個變量時,編譯器為了簡化程序,只要有可能就會把第一次讀取的值放在ACC或Rx中,在以後的讀取該變量的值時就直接使用第一次的讀取值。如果該變量的值在此過程中已經被外設(如讀取外部設備埠時經常將外設埠看作一外部RAM地址)或其他程序(如中斷服務程序)所改變,可能就會出錯。為了解決這類問題,常用的方法就是降低編譯器的優化級別或者使用volatile關鍵字。顯然降低優化級別不是所期望的,因此用volatile關鍵字修飾相關變量很有必要。

上文中的例子將d加上volatile關鍵字後,如下:

重新編譯得到的代碼(部分未列出)如下:

可以看這此y,z變量的值是從d的存儲區中讀取的。這主要是由編譯器的優化早成的,而不是編譯器的錯誤。用volatile變量對變量d修飾後,編譯器不對這個變量的操作進行優化,代碼的執行達到期望的目的。

一般說來,volatile關鍵字用在如下的幾個地方。

(1)中斷服務程序中修改的供其他程序檢測的變量需要加volatile。

(2)多任務環境下各任務間共享的標誌應該加volatile。

(3)存儲器映射的硬體寄存器通常也要加volatile說明,因為每次對它的讀寫都可能有不同意義。

打開APP閱讀更多精彩內容

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容圖片侵權或者其他問題,請聯繫本站作侵刪。 侵權投訴

相關焦點

  • C語言丨深入理解volatile關鍵字
    來源:小職(z_zhizuobiao)找我:✅ 解鎖高薪工作 ✅ 免費獲取乾貨教程在C語言中,還有一個並不常用但卻非常有用的關鍵字volatile。許多程式設計師無法正確的理解C語言關鍵字volatile。這並不奇怪,大多數C原因書籍不過一兩句一帶而過。本文將告訴你如何正確使用它。
  • C語言關鍵詞volatile的用法
    許多程式設計師無法正確的理解C語言關鍵字volatile。這並不奇怪,大多數C原因書籍不過一兩句一帶而過。本文將告訴你如何正確使用它。
  • Java中volatile關鍵字概覽
    一、第一章 volatile關鍵字概覽多線程下變量的不可見性概述在多線程並發執行下,多個線程修改共享的成員變量,會出現一個線程修改了共享變量的值後,另一個線程不能直接 看到該線程修改後的變量的最新值。每一個線程還存在自己的工作內存,線程的工作內存,保留了被線程使用的變量的工作副本。 線程對變量的所有的操作(讀,取)都必須在工作內存中完成,而不能直接讀寫主內存中的變量。不同線程之間也不能直接訪問對方工作內存中的變量,線程間變量的值的傳遞需要通過主內存中轉來完成。
  • 什麼時候需要使用volatile關鍵字
    想必大家平時都見過volatile關鍵字,可是大家知道什麼時候需要使用volatile關鍵字嗎?這裡為了產生預期的行為,需要阻止編譯器做這種優化,可以使用volatile關鍵字修飾。其實const和volatile可以理解為是硬幣的兩面,我們經常聽到看到傳說中的CV修飾詞就是const和volatile關鍵字。volatile可以保證原子性嗎?
  • C語言之const和volatile"究極"學習
    ,修改const全局變量將導致程序崩潰標準c語言編譯器不會將const修飾的全局變量存儲於只讀存儲區中,而是存儲於可修改的全局數據區,其值依然可以改變3、代碼示例:(1)只讀變量代碼示例:#include <stdio.h>int main(){   const int a =10;   printf("a =
  • Java中 volatile 關鍵字的最全總結,趕快給自己查缺補漏吧!
    Java 語言包含兩種內在的同步機制:同步塊(或方法)和 volatile 變量,相比於synchronized(synchronized通常稱為重量級鎖),volatile更輕量級,因為它不會引起線程上下文的切換和調度。但是volatile 變量的同步性較差(有時它更簡單並且開銷更低),而且其使用也更容易出錯。
  • 深度解析volatile關鍵字,就是這麼簡單
    .dylib關鍵字volatile是Java虛擬機提供的最輕量級的同步機制,當一個變量被關鍵字volatile修飾之後,它有如下兩個特性:保證了這個變量對所有線程的可見性禁止指令重排序優化關鍵字volatile可以保證變量對所有線程的可見性,也就是當一個線程修改了這個變量的值,其他線程能夠立即得到修改的值。
  • C語言的那些小秘密之volatile
    通常在代碼中我們為了防止一個變量在意想不到的情況下被改變,我們會將變量定義為volatile,這從而就使得編譯器就不會自作主張的去「動」這個變量的值了。準確點說就是每次在用到這個變量時必須每次都重新從內存中直接讀取這個變量的值,而不是使用保存在寄存器裡的備份。
  • Java內存模型與volatile關鍵字
    Java的內存模型大概樣子還是有必要了解下的,今天就學習了下,順便學習了一點volatile關鍵字!每個線程獲取這類變量都是先把變量從主內存加載到工作內存,然後才能進行使用,同樣如果是修改,那麼也是先修改了工作內存中的變量,然後再從工作內存同步進主內存中。
  • volatile關鍵字詳解
    的三個特點保證線程之間的可見性禁止指令重排不保證原子性可見性概念可見性是多線程場景中才討論的,它表示多線程環境中,當一個線程修改了共享變量的值,其他線程能夠知道這個修改。;    }}class Mythread{    //不加volatile,主線程無法得知num的值發生了改變,從而陷入死循環    volatile int num = 0;    public void increment(){        ++num;    }}
  • Java並發編程徹底搞懂volatile關鍵字
    背景Java線程控制中常用的兩個關鍵字:synchronized、volatile因上篇文章《程式設計師眼中的Synchronized同步鎖》對synchronized本篇文章主要對volatile關鍵字進行解剖。
  • 知名公司面試題:談談你對volatile關鍵字的理解
    作為一名java程式設計師,求職面試時,關於volatile關鍵字時常會遇到。張工最近到某知名網際網路公司面試,面試官提出這樣的一個問題:談談你對volatile關鍵字的理解張工一時間沒有回答上來,面試官:你都工作三年了,怎麼對volatile關鍵字都沒掌握啊。
  • 就是要你懂 Java 中 volatile 關鍵字實現原理
    前言我們知道volatile關鍵字的作用是保證變量在多線程之間的可見性,它是java.util.concurrent包的核心,沒有volatile就沒有這麼多的並發類給我們使用本文詳細解讀一下volatile關鍵字如何保證變量在多線程之間的可見性,在此之前,有必要講解一下CPU緩存的相關知識,掌握這部分知識一定會讓我們更好地理解volatile的原理,從而更好、更正確地地使用volatile關鍵字。
  • 1分鐘讀懂java中的volatile關鍵字
    本文將以儘量簡潔的方式介紹java中的volatile關鍵字。如果覺得寫的不錯,記得,如果寫的不好歡迎批評指正,讓我們一起進步!volatile作為java中的關鍵詞之一,用以聲明變量的值可能隨時會別的線程修改,使用volatile修飾的變量會強制將修改的值立即寫入主存,主存中值的更新會使緩存中的值失效(非volatile變量不具備這樣的特性,非volatile變量的值會被緩存,線程A更新了這個值,線程B讀取這個變量的值時可能讀到的並不是是線程A更新後的值)。
  • 分享牛人解釋的volatile關鍵字
    如果將將變量加上volatile修飾,則編譯器保證對此變量的讀寫操作都不會被優化(肯定執行)。此例中i也應該如此說明。volatile 的含義volatile總是與優化有關,編譯器有一種技術叫做數據流分析,分析程序中的變量在哪裡賦值、在哪裡使用、在哪裡失效,分析結果可以用於常量合併,常量傳播等優化,進一步可以死代碼消除。
  • 可惜了,面試敗在了volatile關鍵字上,直擊痛點搞懂volatile
    寫的內存語義如下:當寫一個volatile變量時,JMM會把該線程對應的本地中的共享變量值刷新到主內存。中重點說下volatile讀後面為什麼跟了個LoadLoad。加入我有如下代碼 AB兩個線程執行,B線程的flag獲取下面的讀被提前了。volatile的實現原理有volatile變量修飾的共享變量進行寫操作的時候會使用CPU提供的Lock前綴指令。
  • 你應該要理解的java並發關鍵字volatile
    提高java的並發編程,就不得不提volatile關鍵字,不管是在面試還是實際開發中 volatile都是一個應該掌握的技能。他的重要性不言而喻。因此也有必要學好。一、為什麼要用到volatile關鍵字?
  • 如何理解volatile關鍵字
    面試中常常會問道,說說你對volatile的理解?在講解之前,我們先來了解一個Java並發編程中可見性的問題。Java並發編程中的可見性問題上圖中每個線程都有自己的工作內存,還有一個共享的主內存。當這兩個線程需要讀取變量data的值的時候,他們需要先從主內存將data變量的值加載到自己的工作內存,才可以使用這個值。
  • 理解 C 語言中的關鍵字 extern
    我確定這篇文章對c語言的初學者會有很大的幫助,因為這將使他們更好更熟練的使用c語言。所以就讓我先來說說extern關鍵字在變量和函數上的應用。
  • Java裡面volatile關鍵字修飾引用變量的陷阱
    Java裡面volatile關鍵字修飾引用變量的陷阱如果我現在問你volatile的關鍵字的作用,你可能會回答對於一個線程修改的變量對其他的線程立即可見。嚴謹的回答應該是volatile關鍵字對於基本類型的修改可以在隨後對多個線程的讀保持一致,但是對於引用類型如數組,實體bean,僅僅保證引用的可見性,但並不保證引用內容的可見性。