|
出招表七:信號(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í)行的先后順序) 在這個(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)張圖: 這下感覺(jué)怎樣,好多了吧... 說(shuō)句真的,我都沒(méi)想到,這點(diǎn)東西要將那么久,雖然不愿意,但只能說(shuō):欲知后事如何,咱們下回接著再聊.. |
|
|