电竞比分网-中国电竞赛事及体育赛事平台

分享

Linux內(nèi)核開(kāi)發(fā)之并發(fā)控制(四)

 看風(fēng)景D人 2014-07-19

出招表七:信號(hào)量(信號(hào)量其實(shí)和自旋鎖是一樣的,就是有一點(diǎn)不同:當(dāng)獲取不到信號(hào)量時(shí),進(jìn)程不會(huì)原地打轉(zhuǎn)而是進(jìn)入休眠等待狀態(tài))

Linux系統(tǒng)中與信號(hào)量相關(guān)的操作主要有一下4種:

1)定義信號(hào)量    struct semaphore sem;

2)初始化信號(hào)量   

void sema_init (struct semphore *sem, int val);    //設(shè)置sem為val

void init_MUTEX(struct semaphore *sem);    //初始化一個(gè)用戶(hù)互斥的信號(hào)量sem設(shè)置為1

void init_MUTEX_LOCKED(struct semaphore *sem);    //初始化一個(gè)用戶(hù)互斥的信號(hào)量sem設(shè)置為0

DECLARE_MUTEX(name);     //該宏定義信號(hào)量name并初始化1

DECLARE_MUTEX_LOCKED(name);    //該宏定義信號(hào)量name并初始化0

3)獲得信號(hào)量

void down(struct semaphore *sem);    //該函數(shù)用于獲取信號(hào)量sem,會(huì)導(dǎo)致睡眠,不能被信號(hào)打斷,所以不能在中斷上下文使用。

int down_interruptible(struct semaphore *sem);    //因其進(jìn)入睡眠狀態(tài)的進(jìn)程能被信號(hào)打斷,信號(hào)也會(huì)導(dǎo)致該函數(shù)返回,這是返回非0。

int down_trylock(struct semaphore *sem);//嘗試獲得信號(hào)量sem,如果能夠獲得,就獲得并返回0,否則返回非0,不會(huì)導(dǎo)致調(diào)用者睡眠,可以在中斷上下文使用

一般這樣使用

if(down_interruptible(&sem))

{

    return  - ERESTARTSYS;

}

4)釋放信號(hào)量

void up(struct semaphore *sem);    //釋放信號(hào)量sem,喚醒等待者

信號(hào)量一般這樣被使用,如下所示:

//定義信號(hào)量

DECLARE_MUTEX(mount_sem);

down(&mount_sem);//獲取信號(hào)量,保護(hù)臨界區(qū)

critical section //臨界區(qū)

up(&mount_sem);

好了,下邊給大家一個(gè)例子看看使用信號(hào)量來(lái)實(shí)現(xiàn)設(shè)備只能被一個(gè)進(jìn)程打開(kāi)的例子:

static DECLARE_MUTEX(xxx_lock);//定義互斥鎖

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

{

   …

   if(down_trylock(&xxx_lock))    //獲得打開(kāi)鎖

       return – EBUSY; //設(shè)備忙

   …

   return 0;//成功

}

 

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

{

    up(&xxx_lock);    //釋放打開(kāi)鎖

    return 0;

}

在上面介紹的有關(guān)信號(hào)量的操作中,我們提到了一個(gè)問(wèn)題就是信號(hào)量的初始化問(wèn)題,一般對(duì)信號(hào)量的初始化是沒(méi)有限制的,但如果信號(hào)量被初始化為0,則它可以用于同步,說(shuō)到這里,就不得不介紹新的一招了

 

出招表八:同步(它意味著一個(gè)執(zhí)行單元的繼續(xù)執(zhí)行需要等待另一個(gè)執(zhí)行單元完成其事,保證了執(zhí)行的先后順序)

    tongbu

在這個(gè)圖中,執(zhí)行單元A執(zhí)行代碼區(qū)域b之前,必須等待執(zhí)行單元B執(zhí)行完代碼單元c,而信號(hào)量剛好可輔助完成這一同步過(guò)程. 

 

這時(shí)你可能要問(wèn),像這樣的同步,在現(xiàn)實(shí)中可是常常遇到.比如,報(bào)名時(shí)必須等前一項(xiàng)完成了才能完成后一項(xiàng)..等等,是不是同步就這么一種方式啊..

呵呵,真聰明,小菜終于長(zhǎng)大了,成為大菜了.其實(shí),Linux系統(tǒng)提供了一種更好的同步機(jī)制----完成量,好吧,看在你求學(xué)若渴的份上,就把它一起傳授給你了,不收費(fèi)哦,呵呵

出招表九:完成量(completion),它用于一個(gè)執(zhí)行單元等待另一個(gè)執(zhí)行單元執(zhí)行完某事

使用方法:1)定義完成量

            struct completion my_completion;

            2)初始化

            init_completion(&my_completion); //要是覺(jué)得這兩步麻煩,就再給你來(lái)個(gè)宏即定義又初始化DECLARE_COMPLETION(my_completion);

            3)等待完成量

            void wait_for_completion(structcompletion *c);   //等待一個(gè)completion被喚醒

            wait_for_completion_interruptible(struct completion *c); //可中斷的wait_for_completion

            unsigned long wait_for_completion_timeout(struct completion *x,unsigned long timeout);  //帶超時(shí)處理的wait_for_completion

            4)喚醒完成量

            void complete(struct completion *c);   //只喚醒一個(gè)等待的執(zhí)行單元。

            void complete_all(struct completion *c);   //喚醒所有等待這個(gè)完成量的執(zhí)行單元

瞧我這記性,說(shuō)了這么多,怎么就忘了給出completion結(jié)構(gòu)體呢:

struct completion

{ 

     unsigned int done;//標(biāo)志是否已經(jīng)做完,未做完就是負(fù)值,代表等待個(gè)數(shù),完成為0

     wait_queue_head_t wait;

如果覺(jué)得不太理解,不過(guò)癮,就給你來(lái)張圖:

   completion

這下感覺(jué)怎樣,好多了吧...

說(shuō)句真的,我都沒(méi)想到,這點(diǎn)東西要將那么久,雖然不愿意,但只能說(shuō):欲知后事如何,咱們下回接著再聊..

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多