<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > linux系統(tǒng)編程之基礎(chǔ)必備(六):可重入函數(shù)、sig

          linux系統(tǒng)編程之基礎(chǔ)必備(六):可重入函數(shù)、sig

          作者: 時(shí)間:2016-10-08 來(lái)源:網(wǎng)絡(luò) 收藏

          是編譯器優(yōu)化得有錯(cuò)誤嗎?不是的。設(shè)想一下,如果程序只有單一的執(zhí)行流程,只要當(dāng)前執(zhí)行流程沒(méi)有改變a的值,a的值就沒(méi)有理由會(huì)變,不需要反復(fù)從內(nèi)存讀取,因此上面的兩條指令和while(!a);循環(huán)是等價(jià)的,并且優(yōu)化之后省去了每次循環(huán)讀內(nèi)存的操作,效率非常高。

          所以不能說(shuō)編譯器做錯(cuò)了,只能說(shuō)編譯器無(wú)法識(shí)別程序中存在多個(gè)執(zhí)行流程。之所以程序中存在多個(gè)執(zhí)行流程,是因?yàn)檎{(diào)用了特定平臺(tái)上的特定庫(kù)函數(shù),比如sigaction、pthread_create,這些不是C語(yǔ)言本身的規(guī)范,不歸編譯器管,程序員應(yīng)該自己處理這些問(wèn)題。

          C語(yǔ)言提供了volatile限定符,如果將上述變量定義為volatile sig_atomic_t a=0;那么即使指定了優(yōu)化選項(xiàng),編譯器也不會(huì)優(yōu)化掉對(duì)變量a內(nèi)存單元的讀寫(xiě)。

          對(duì)于程序中存在多個(gè)執(zhí)行流程訪問(wèn)同一全局變量的情況,volatile限定符是必要的,此外,雖然程序只有單一的執(zhí)行流程,但是變量屬于以下情況之一的,也需要volatile限定:

          變量的內(nèi)存單元中的數(shù)據(jù)不需要寫(xiě)操作就可以自己發(fā)生變化,每次讀上來(lái)的值都可能不一樣;

          即使多次向變量的內(nèi)存單元中寫(xiě)數(shù)據(jù),只寫(xiě)不讀,也并不是在做無(wú)用功,而是有特殊意義的;

          什么樣的內(nèi)存單元會(huì)具有這樣的特性呢?肯定不是普通的內(nèi)存,而是映射到內(nèi)存地址空間的硬件寄存器,例如串口的

          接收寄存器屬于上述第一種情況,而發(fā)送寄存器屬于上述第二種情況。

          sig_atomic_t類型的變量應(yīng)該總是加上volatile限定符,因?yàn)橐褂胹ig_atomic_t類型的理由也正是

          要加volatile限定符的理由。

          對(duì)于多線程的程序,訪問(wèn)沖突的問(wèn)題是很普遍的,解決的辦法是引入鎖,獲得鎖的線程可以完成“讀-修改-寫(xiě)”的操作,然后釋放鎖給其它線程,沒(méi)有獲得鎖的線程只能等待而不能訪問(wèn)共享數(shù)據(jù),這樣“讀-修改-寫(xiě)”三步操作組成一個(gè)原子操作,要么都執(zhí)行,要么都不執(zhí)行,不會(huì)執(zhí)行到中間被打斷,也不會(huì)在其它處理器上并行做這個(gè)操作。


          上一頁(yè) 1 2 下一頁(yè)

          關(guān)鍵詞:

          評(píng)論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();