歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Linux設備驅動中的並發控制

並發是多個執行單元同時 並行被執行。而並發的執行單元對共享資源(硬件資源和軟件上的全局變量,靜態變量)的訪問很容易導致競態。

主要的競態有以下三種情況:對稱多處理器(SMP)的多個CPU;單個CPU內進程與搶占它的進程;中斷(硬中斷,軟中斷,Tasklet 底半部)與進程之間。

注:上述情況,除了SMP是真正的並行之外,其他的都是“宏觀並行,微觀串行”,但其引發的問題和SMP相似。

解決競態問題的途徑是保證對共享資源的互斥訪問,即:當一個進程訪問的時候,其他的進程單元禁止訪問。

訪問共享資源的代碼區稱為臨界區。訪問臨界區即需要加互斥機制。

實現互斥訪問的途徑有如下幾種:

1 . 中斷屏蔽
2 . 原子操作
3 . 自旋鎖
4 . 信號量 

1 . 中斷屏蔽

CPU 一般都具備屏蔽中斷和打開中斷的功能,這使得正在執行的內核執行路徑不被中斷處理程序搶占,防止了競態的放生

使用方法:

local_irq_disable()//屏蔽中斷

。。。

critical section //臨界區

。。。

local_irq_enable()//開啟中斷

 

2 . 原子操作

原子操作是指在執行的過程中不會被別的代碼路徑所中斷的操作。

有兩類函數可以實現原子操作:針對位 和針對整形變量的操作

整型原子操作:

1 設置原子變量的值

void atomic_set(atomic_t  *v,int  t);//設置值為i

atomic_t v= ATOMIC_INIT(0);//初始化

 

2 獲取原子變量的值

atomic_read(atomic_t *v);

 

3 原子變量加/減

void atomic_add(atomic_t *v);

void atomic_sub(atomic_t *v);

 

4 原子變量自增/自減

void atomic_inc(atomic_t *v);

void atomic_dec(atomic_t *v);

 

5 操作並測試

int atomic_inc_and_test(atomic_t *v);

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);

int atomic_sub_return(int i, atomic_t *v);

int atomic_inc_return(atomic_t *v);

int atomic_dec_return(atomic_t *v);

 

 位原子操作

1 設置位

void set_bit(nr,void *addr)

 

2 清除位

void clear_bit(nr,void *addr)

 

3 改變位

void change_bit(nr,void *addr)

 

4 測試位

void test_bit(nr,void *addr)

 

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);

Copyright © Linux教程網 All Rights Reserved