日本免费全黄少妇一区二区三区-高清无码一区二区三区四区-欧美中文字幕日韩在线观看-国产福利诱惑在线网站-国产中文字幕一区在线-亚洲欧美精品日韩一区-久久国产精品国产精品国产-国产精久久久久久一区二区三区-欧美亚洲国产精品久久久久

高手進(jìn)階必讀:Linux內(nèi)核的同步機(jī)制

本文詳細(xì)的介紹了Linux內(nèi)核中的同步機(jī)制:原子操作、信號(hào)量、讀寫信號(hào)量和自旋鎖的API , 使用要求以及一些典型示例

一、引言

在現(xiàn)代操作系統(tǒng)里 , 同一時(shí)間可能有多個(gè)內(nèi)核執(zhí)行流在執(zhí)行 , 因此內(nèi)核其實(shí)象多進(jìn)程多線程編程一樣也需要一些同步機(jī)制來(lái)同步各執(zhí)行單元對(duì)共享數(shù)據(jù)的訪問 。尤其是在多處理器系統(tǒng)上 , 更需要一些同步機(jī)制來(lái)同步不同處理器上的執(zhí)行單元對(duì)共享的數(shù)據(jù)的訪問 。

在主流的Linux內(nèi)核中包含了幾乎所有現(xiàn)代的操作系統(tǒng)具有的同步機(jī)制 , 這些同步機(jī)制包括:原子操作、信號(hào)量(semaphore)、讀寫信號(hào)量(rw_semaphore)、spinlock、BKL(Big Kernel Lock)、rwlock、brlock(只包含在2.4內(nèi)核中)、RCU(只包含在2.6內(nèi)核中)和seqlock(只包含在2.6內(nèi)核中) 。

二、原子操作

所謂原子操作 , 就是該操作絕不會(huì)在執(zhí)行完畢前被任何其他任務(wù)或事件打斷 , 也就說 , 它的最小的執(zhí)行單位 , 不可能有比它更小的執(zhí)行單位 , 因此這里的原子實(shí)際是使用了物理學(xué)里的物質(zhì)微粒的概念 。

原子操作需要硬件的支持 , 因此是架構(gòu)相關(guān)的 , 其API和原子類型的定義都定義在內(nèi)核源碼樹的include/asm/atomic.h文件中 , 它們都使用匯編語(yǔ)言實(shí)現(xiàn) , 因?yàn)镃語(yǔ)言并不能實(shí)現(xiàn)這樣的操作 。

原子操作主要用于實(shí)現(xiàn)資源計(jì)數(shù) , 很多引用計(jì)數(shù)(refcnt)就是通過原子操作實(shí)現(xiàn)的 。原子類型定義如下:

typedef struct{volatile int counter;}atomic_t;
volatile修飾字段告訴gcc不要對(duì)該類型的數(shù)據(jù)做優(yōu)化處理 , 對(duì)它的訪問都是對(duì)內(nèi)存的訪問 , 而不是對(duì)寄存器的訪問 。

原子操作API包括:
atomic_read(atomic_t * v);
該函數(shù)對(duì)原子類型的變量進(jìn)行原子讀操作 , 它返回原子類型的變量v的值 。

atomic_set(atomic_t * v, int i);
該函數(shù)設(shè)置原子類型的變量v的值為i 。

void atomic_add(int i, atomic_t *v);
該函數(shù)給原子類型的變量v增加值i 。

atomic_sub(int i, atomic_t *v);
該函數(shù)從原子類型的變量v中減去i 。

int atomic_sub_and_test(int i, atomic_t *v);
該函數(shù)從原子類型的變量v中減去i , 并判斷結(jié)果是否為0 , 如果為0 , 返回真 , 否則返回假 。

void atomic_inc(atomic_t *v);
該函數(shù)對(duì)原子類型變量v原子地增加1 。

void atomic_dec(atomic_t *v);
該函數(shù)對(duì)原子類型的變量v原子地減1 。

int atomic_dec_and_test(atomic_t *v);
該函數(shù)對(duì)原子類型的變量v原子地減1 , 并判斷結(jié)果是否為0 , 如果為0 , 返回真 , 否則返回假 。

int atomic_inc_and_test(atomic_t *v);
該函數(shù)對(duì)原子類型的變量v原子地增加1 , 并判斷結(jié)果是否為0 , 如果為0 , 返回真 , 否則返回假 。

int atomic_add_negative(int i, atomic_t *v);
該函數(shù)對(duì)原子類型的變量v原子地增加I , 并判斷結(jié)果是否為負(fù)數(shù) , 如果是 , 返回真 , 否則返回假 。

int atomic_add_return(int i, atomic_t *v);
該函數(shù)對(duì)原子類型的變量v原子地增加i , 并且返回指向v的指針 。

int atomic_sub_return(int i, atomic_t *v);
該函數(shù)從原子類型的變量v中減去i , 并且返回指向v的指針 。

int atomic_inc_return(atomic_t * v);
該函數(shù)對(duì)原子類型的變量v原子地增加1并且返回指向v的指針 。

int atomic_dec_return(atomic_t * v);【高手進(jìn)階必讀:Linux內(nèi)核的同步機(jī)制】該函數(shù)對(duì)原子類型的變量v原子地減1并且返回指向v的指針 。

原子操作通常用于實(shí)現(xiàn)資源的引用計(jì)數(shù) , 在TCP/IP協(xié)議棧的IP碎片處理中 , 就使用了引用計(jì)數(shù) , 碎片隊(duì)列結(jié)構(gòu)struct ipq描述了一個(gè)IP碎片 , 字段refcnt就是引用計(jì)數(shù)器 , 它的類型為atomic_t , 當(dāng)創(chuàng)建IP碎片時(shí)(在函數(shù)ip_frag_create中) , 使用atomic_set函數(shù)把它設(shè)置為1 , 當(dāng)引用該IP碎片時(shí) , 就使用函數(shù)atomic_inc把引用計(jì)數(shù)加1 。

推薦閱讀