並發:
多個執行單元同時被執行.
競態:
並發的執行單元對資源 ( 硬件資源和軟件上的全局變量等 ) 的訪問導致的競爭狀態.
並發的處理:
處理並發的常用技術是加鎖或者互斥,即保證在任何時間只有一個執行單元可以操作共享資源.
在 Linux 內核中主要通過 semaphore 機制 (信號量)和spin_lock 機制 (自旋鎖)實現.
原子操作:
定義:
原子操作指的是在執行過程中不會被別的代碼所中斷的操作.
分為 位 和 整型變量 兩類原子操作。
atomic_t :
- typedef struct {
- volatile int counter;
- } atomic_t;
原子操作函數:
整型原子操作:
- void atomic_set(atomic_t *v, int i); //設置原子變量v的值為i
- atomic_t v = ATOMIC_INIT(0); //定義原子變量v, 並初始化為0 **************************
- atomic_read(atomic_t *v); //獲得原子變量的值,返回原子變量的值
- void atomic_add(int i, atomic_t *v); //原子變量+i
- void atomic_sub(int i, atomic_t *v); //原子變量-i
- void atomic_inc(atomic_t *v); //原子變量+1 *******************************
- void atomic_dec(atomic_t *v); //原子變量-1
對原子變量執行自增,自減和減操作后 ,測試其是否為0,為 0 則返回 true,否則返回 false :
- 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);
對原子變量進行加/減,自增/自減操作,並返回新的值:
- 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_sub_return(atomic_t *v);
位原子操作:
- void set_bit(nr, void *addr); //將addr地址的nr位 置為1
- void clear_bit(nr, void *addr); //將addr地址的nr位 清0
- void change_bit(nr, void *addr); //對addr地址的nr位 反置
- int test_bit(nr, void *addr); //返回addr地址的nr位
- int test_and_set_bit(nr, void *addr);
- int test_and_clear_bit(nr, void *addr);
- int test_and_change_bit(nr, void *addr);
- 先設值,后返回。
實例 --- 原子操作:
1,定義一原子變量:
在程序開頭定義原子變量,初始化為 1 :
- static atomic_t canopen = ATOMIC_INIT(1); //定義原子變量並初始化為1
2,在 open 函數里檢測原子變量值:
如果減 一 為 0 , !true 為 假 ,if 里面的原子變量加一恢復到 0,
- {
- atomic_inc(&canopen);
- return -EBUSY;
- }
3,在退出時 close 函數 恢復原子變量值:
最后, 在應用程序退出時 close 函數, 自增 恢復原子變量值為 1:
- atomic_inc(&canopen);
4,應用程序測試:
在應用程序里面打開驅動程序:
- fd = open("/dev/buttons", O_RDWR);
- if (fd < 0)
- {
- printf("can't open!\n");
- return -1;
- }
當有兩個應用程序打開同一這個驅動的時候,打印 can't open! .