Linux核心併發機制 原子操作

2021-08-22 05:56:17 字數 4523 閱讀 7796

很多人會問這樣的問題,linux核心中提供了各式各樣的鎖機制到底有何作用?追根到底其實是由於作業系統中存在多程序對共享資源的併發訪問,從而引起了程序間的競態。這其中包括了我們所熟知的smp系統,多核間的相互競爭資源,單cpu之間的相互競爭,中斷和程序間的相互搶占等諸多問題。

所謂的原子操作,就是該操作絕不會在執行完畢前被任何其他任務或事件打斷,也就是說,它的最小的執行單位,不能有比它更小的執行單元,因此這裡的原子實際是使用了物理學裡物質微粒的概念。

linux提供了一組操作來保證對變數的原子操作。這些操作可用來避免簡單的競爭條件。原子操作執行時不會被打斷或干擾。在單處理器上,一旦啟動原子操作,則從操作開始到結束的這段 時間內,不會中斷執行緒。此外,在多處理器系統中,原子操作所針對的變數被鎖定,以免被其他程序訪問,直到原子操作結束。

原子操作主要用來實現資源計數,很多引用計數就是通過原子操作實現的。

typedef struct atomic_t;

該函式對原子型別的變數進行原子讀操作,它返回原子型別的變數v的值。

(1)atomic_read(atomic_t *v)

該函式設定原子型別的變數v的值為i。

(2)atomic_set(atomic_t *v,int i);

該函式給原子型別變數v增加i。

(3)atomic_add(int i, atomic_t *v);

該函式給原子型別變數v減去i。

(4)atomic_sub(int i, atomic_t *v);

該函式從原子型別的變數v中減去i,並判斷結果是否是0,如果為0,返回真,否則返回假。

(5)atomic_sub_and_test(int i, atomic_t *v);

該函式對原子變數v的增加1。

(6) atomic_inc(atomic_t *v);

該函式對原子變數v原子的減少1。

(7)atomic_dec(atomic_t *v);

該函式先測試後操作,先判斷結果是否為0,如果是0,返回真,然後對原子變數v減少1.

(8)atomic_dec_and_test(atomic_t *v);

該函式先測試後操作,先判斷結果是否為0,如果是0,返回真,然後對原子變數v增加1.

(9)atomic_inc_and_test(atomic_t *v);

該函式屬於先操作後返回,對原子型別的變數v原子的增加i,並且返回指向新的的指標。

(10)atomic_add_return(int i, atomic_t *v);

該函式屬於先操作後返回,對原子型別的變數v原子的減少i,並且返回指向新的的指標。

(11)atomic_sub_return(int i, atomic_t *v);

#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /*

oop程式設計的思想:

1.設計和分配結構體

2.設定

3.註冊

*/ //static 它的作用域只在本檔案中

#define lkm_name "lkm_memory"

#define lkm_mem_size 1024

//構造物件的結構體

struct lkm_memory_dev;

//建立全域性結構體物件

static struct lkm_memory_dev *plkm_memory_dev;

static int lkm_mem_open(struct inode * pinode, struct file * filep)

return 0;

}//引數四 :位置

static ssize_t lkm_mem_read (struct file *filp, char __user *buf, size_t len, loff_t * pos)

if(count > ptmp)

count=ptmp;

//主要作用就是從核心空間拷貝一塊兒資料到使用者空間

if(copy_to_user(buf,dev->memory+ptmp,count))

else

return iret;

}static ssize_t lkm_mem_write (struct file *filp, const char __user * buf, size_t len, loff_t * pos)

if(count >lkm_mem_size-ptmp)

count=lkm_mem_size-ptmp;

if(copy_from_user(dev->memory+ptmp,buf,count))

else

return iret;

}static int lkm_mem_release(struct inode *pinode, struct file *filep)

//分配

static struct file_operations lkm_mem_fops=;

static int lkm_memory_setup_dev(struct lkm_memory_dev * dev,int index)

static __init int lkm_init(void)

//對lkm進行設定

//對lkm_mem_name 分配乙個記憶體

plkm_memory_dev->lkm_mem_name=kzalloc(sizeof(lkm_name), gfp_kernel);

if( !plkm_memory_dev->lkm_mem_name)

//對name 賦值

memcpy(plkm_memory_dev->lkm_mem_name,lkm_name,sizeof(lkm_name));

plkm_memory_dev->fops=&lkm_mem_fops;

plkm_memory_dev->lkm_mem_major= register_chrdev(0, plkm_memory_dev->lkm_mem_name,plkm_memory_dev->fops);

if (plkm_memory_dev->lkm_mem_major< 0)

//呼叫當前的lkm結構體綜合設定函式

iret=lkm_memory_setup_dev(plkm_memory_dev,0);

if(!iret)

plkm_memory_dev->lkm_mem_class = class_create(this_module, plkm_memory_dev->lkm_mem_name);

if (is_err(plkm_memory_dev->lkm_mem_class))

//devt相當於num

//主從裝置號的合體

//主裝置號對應乙個類

//從裝置號對應乙個相應的裝置

linux核心同步機制之原子操作(基於ARM)

linux 使用 乙個變數atomic t來表示原子變數。typedef struct atomic t 可以看到裡面是乙個int 型別的變數。這裡只分析乙個atomic add函式 static inline void atomic add int i,atomic t v 如下,可以看到linu...

驅動程式的併發機制 原子操作

乙個硬體裝置會被多個程序同時使用,這就是併發,併發會導致裝置亂序。例如scull裝置就有可能在a 程序正在執行scull read 函式 但尚未執行完 的時候就被b 程序打斷,而b 程序執行的是scull write 函式,當a 程序再次被執行的時候它讀到的東西就不再是它以前應該讀到的東西。要解決這...

Linux原子操作,讀寫鎖機制

若干組合語言指令具有 讀 修改 寫 型別 也就是說,他們訪問儲存單元兩次,第一次讀原值,第二次寫新值。假定執行在兩個cpu上的兩個核心控制路徑試圖通過執行非原子操作來同時 讀 修改 寫 同乙個儲存器單元。首先,兩個cpu都試圖讀同乙個單元,但是儲存器仲裁器 對訪問ram晶元的操作進行序列化的硬體電路...