<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > Linux內核開(kāi)發(fā)之并發(fā)控制(一)

Linux內核開(kāi)發(fā)之并發(fā)控制(一)

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

  “小濤,你說(shuō)十一黃金周,火車(chē)站,飛機場(chǎng)那些售票系統咋沒(méi)一個(gè)宕掉的呢。你不宕掉也沒(méi)關(guān)系,來(lái)兩個(gè)賣(mài)錯票的,說(shuō)不定哥就去上??词啦?,去北京看青梅竹馬的表妹了…”小王抱怨道。

本文引用地址:http://dyxdggzs.com/article/201612/341755.htm

  “暈死..哥鄙視你,你說(shuō)都老大不小的人了,怎么腦子里天天都是MM之類(lèi)的事了,能不能有點(diǎn)男子氣概啊..”。

  “靠,能跟你比啊,你是飽漢不知餓漢饑,要是像你一樣十一和…”

  "嗯,啊,哼哼.."沒(méi)等他說(shuō)完,我趕忙塞了雙臭襪子(哪天的也記不住了)?!暗玫?,I 服了 you,ok”。

  “不過(guò)話(huà)說(shuō)回來(lái),小王,你說(shuō)的還真是個(gè)問(wèn)題,想想這樣的問(wèn)題,你和GF兩個(gè)要去西湖看白娘子,偏偏遇到老天跟你過(guò)不去,就只剩下一張票了,你和GF兩個(gè)誰(shuí)去…“

  "不是吧,我這命苦,好不容易有個(gè)GF,應該不會(huì )出現的,呵呵,如果出現…那好辦,我和她商量好,咱們一起在晚上12:00一起買(mǎi)票,這樣我們兩邊的售票員怎么看都各自有一張票,我們兩個(gè)就可以一起了"小王狡黠的笑著(zhù)。

  “笨,我一口一個(gè)鹽水噴死你,分明一張票,你們兩個(gè)同一個(gè)時(shí)間去兩個(gè)不同的售票點(diǎn)去買(mǎi),它還是一張票,怎么可能說(shuō)去兩個(gè)不同地方,兩個(gè)售票員都看到有一張票,然后就把這唯一的一張同時(shí)賣(mài)給了你們兩個(gè)人”我打斷到。"算了,看在室友兼我的最忠實(shí)狗仔隊員的身份,哥就傳授一招只傳MM的絕學(xué)----設備驅動(dòng)程序之并發(fā)控制"。

  聽(tīng)說(shuō)過(guò)并發(fā)沒(méi),那你肯定聽(tīng)說(shuō)過(guò)競爭,比如競爭上崗,還有你最熟悉的追MM,這也是競爭。那么

  并發(fā)(concurrency)就是說(shuō)多個(gè)執行單元同時(shí),并行被執行,這多個(gè)單元卻不巧要同時(shí)訪(fǎng)問(wèn)一些資源。這其中要分三種情況:

    

 

  正所謂:道高一尺,魔高一丈,你孫悟空有72變,人家二郎神還有73變不是。有問(wèn)題,沒(méi)關(guān)系,找小濤哥不是..呵呵?,F在就教你幾招以備不時(shí)只需:

  大家不是要競爭嗎,那好,總體原則就是不讓你競爭:保證一個(gè)執行單元在訪(fǎng)問(wèn)共享資源的時(shí)候,其他的執行單元被禁止訪(fǎng)問(wèn),將競爭扼殺在萌芽狀態(tài)。這就是傳說(shuō)中的對共享資源的互斥訪(fǎng)問(wèn)。

  出招表一:中斷屏蔽(可以保證正在執行的執行路徑不被中斷處理程序搶占,由于的進(jìn)程調度都依賴(lài)中斷來(lái)實(shí)現,搶占進(jìn)程之間的競態(tài)就不存在了)

  使用方法: local_irq_disable() //屏蔽中斷 說(shuō)明:local_irq_disable()和local_irq_enable()都只能禁止和使能本CPU內的中斷

  …. 并不能解決SMP多CPU引發(fā)的競爭。

  critical section //臨界區

  ….

  local_irq_enable() //開(kāi)中斷

  與local_irq_disable()不同,local_irq_save(flags)除了進(jìn)行禁止中斷操作以外,還保證目前CPU的中斷位信息,local_irq_save(flags)進(jìn)行相反的操作。

  致命弱點(diǎn): 由于系統的異步I/O,進(jìn)程調度等很多重要操作都依賴(lài)于中斷,在屏蔽中斷期間所有的中斷都無(wú)法處理,因此長(cháng)時(shí)間屏蔽中斷是很危險的,有可能造

  成數據丟失甚至系統奔潰。

  出招表二:原子操作(忘了是物理還是化學(xué)老師拉著(zhù)我的手說(shuō):原子是最小的,不能再分的東西.看多形象,執行過(guò)程不能被別的代碼路徑中斷的操作就是原子操作,還

  想跟我競爭,門(mén)都沒(méi)有)。 分為整形原子和位原子操作。

  使用方法一:整形原子操作

  1)設置原子變量的值

  void atomic_set(atomic_t *v, int i);//設置原子變量的值為i

  atomic_t v = ATOMIC_INIT(0);//定義原子變量v并初始化為0

  2)獲取原子變量的值

  atomic_read(atomic_t *v);//返回原子變量的值

  3)原子變量加/減

  void atomic_add(int i,atomic_t *v); //原子變量增加i

  void atomic_sub(int i,atomic_t *v); //原子變量減少i

  4)原子變量自增/自減

  void atomic_inc(atomic_t *v); //原子變量加1

  void atomic_dec(atomic_t *v); //原子變量減1

  5)操作并測試

  int atomic_inc_and_test(atomic_t *v);//這些操作對原子變量執行自增,自減,減操作后測試是否為0,是返回true,否則返回false

  int atomic_dec_and_test(atomic_t *v);

  int atomic_sub_and_test(int i, atomic_t *v);

  6)操作并返回

  int atomic_add_return(int i,atomic_t *v); //這些操作對原子變量進(jìn)行對應操作,并返回新的值。

  int atomic_sub_return(int i, atomic_t *v);

  int atomic_inc_return(atomic *v);

  int atomic_dec_return(atomic_t *v);

  使用方法二:位原子操作。

  1)設置位

  void set_bit(nr, void *addr); //設置addr地址的第nr位,所謂設置位即將位寫(xiě)為1

  2)清除位

  void clear_bit(nr,void *addr); //清除addr地址的第nr位,所謂清除位即將位寫(xiě)為0

  3)改變位

  void change_bit(nr,void *addr); //對addr地址的第nr位反置

  4)測試位

  void test_bit(nr, void *addr); //返回addr地址的第nr位

  5)測試并操作位

  int test_and_set_bit(nr, void *addr);

  int test_and_clear_bit(nr, void *addr);

  int test_and_change_bit(nr, void *addr);

  光說(shuō)不練,不是好漢。這誰(shuí)說(shuō)的呢,咋就是記不得呢,看段代碼:

  static atomic_t ato_avi = ATOMIC_INIT(1); //定義原子變量

  static int ato_open(struct inode *inode, struct file *filp)

  {

  ...

  if (!atomic_dec_and_test(&ato_avi))

  {

  atomic_inc(&ato_avi);

  return = - EBUSY; //已經(jīng)打開(kāi)

  }

  ..

  return 0; //已經(jīng)打開(kāi)

  }

  static int ato_release(struct inode *inode, struct file *filp)

  {

  atomic_inc(&ato_avi);

  return 0;

  }

  出招表三:自旋鎖。正如其名,CPU上將要執行的代碼將會(huì )執行一個(gè)測試并設置某個(gè)內存變量的原子操作,若測試結果表明鎖已經(jīng)空閑,則程序獲得這個(gè)自旋

  鎖繼續運行;若仍被占用,則程序將在一個(gè)小的循環(huán)內重復測試這個(gè)"測試并設置"的操作.這就是自旋。

  使用方法:1)spinlock_t spin; //定義自旋鎖

  2)spin_lock_init(lock); //初始化自旋鎖

  3)spin_lock(lock); //成功獲得自旋鎖立即返回,否則自旋在那里直到該自旋鎖的保持者釋放

  spin_trylock(lock); //成功獲得自旋鎖立即返回真,否則返回假,而不是像上一個(gè)那樣"在原地打轉"

  4)spin_unlock(lock);//釋放自旋鎖

  自旋鎖一般像下邊這樣使用:

  spinlock_t lock;

  spin_lock_init(&lock);

  spin_lock (&lock);

  ....//臨界區

  spin_unlock(&lock);

  還記的前邊說(shuō)的第一招:中斷屏蔽中致命的弱點(diǎn)步,自旋鎖就是針對SMP或單個(gè)CPU但內核可搶占的情況,對于但CPU和內核不可搶占的系統,自旋鎖退化為空操作。還有就是自旋鎖解決了臨界區不受別的CPU和本CPU內的搶占進(jìn)程打擾,但是得到鎖的代碼路徑在執行臨界區的時(shí)候還可能受到中斷和底半部的影響。

  那咋辦呢,天要下雨,娘要嫁人,可二郎神的就是比你孫悟空多了一變,你能咋辦,打一架?打不過(guò)..所以說(shuō)嘛,Linux社區的開(kāi)發(fā)者們早想到了辦法:在自旋鎖的基礎上進(jìn)行衍生,具體是怎么回事,且聽(tīng)下回分解(每次說(shuō)這句話(huà)是感覺(jué)好爽,這難道就是高手??岬臉?lè )趣..)..



關(guān)鍵詞: Linux 內核

評論


相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>