日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

字符设备驱动程序之按键——同步互斥阻塞

發(fā)布時(shí)間:2024/9/3 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 字符设备驱动程序之按键——同步互斥阻塞 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
我們知道在之前的應(yīng)用程序中,如果我們同時(shí)運(yùn)行兩次應(yīng)用程序的話(huà),則兩次都可以同時(shí)打開(kāi)設(shè)備,這就是說(shuō)我們的按鍵資源同時(shí)被兩個(gè)進(jìn)程使用。顯然這不是我們想要的,那么下面我們就要引入互斥的概念。 關(guān)于互斥其實(shí)其實(shí)現(xiàn)很簡(jiǎn)單,就是采用一些標(biāo)志,當(dāng)文件被一個(gè)進(jìn)程打開(kāi)后,就會(huì)設(shè)置該標(biāo)志,使其他進(jìn)程無(wú)法打開(kāi)設(shè)備文件。下面,我們就完全靠自己去實(shí)現(xiàn)一個(gè)互斥,代碼修改如下:
首先定義一個(gè)全局變量: static int canread=1; 然后在open函數(shù)開(kāi)始處加入如下代碼: ? if(--canread!=0) ? ? ? ? { ? ? ? ? ?? ? ? ? ? ? ? canread++; ? ? ? ? ? ? return -EBUSY; ? ? ? ? } 在close函數(shù)里面加入如下代碼: anread++; 我們可以先分析一下,當(dāng)進(jìn)程A打開(kāi)設(shè)備文件時(shí),因?yàn)槌跏贾礳anread=1,canread減1后正好等于0,不會(huì)出錯(cuò)返回,成功打開(kāi)了。此時(shí)當(dāng)進(jìn)程B再來(lái)打開(kāi)該設(shè)備文件時(shí),因canread=0,canread減1不為0,所以會(huì)出錯(cuò)出錯(cuò)返回,且canread加1,canread=0。當(dāng)進(jìn)程A關(guān)閉后,canread加1,canread=1;這時(shí)如果B進(jìn)程運(yùn)行,會(huì)成功打開(kāi)設(shè)備文件。看上去似乎完美得實(shí)現(xiàn)了互斥,其實(shí)這其中是有問(wèn)題的。因?yàn)槠鋵?shí)對(duì)于: ?--canread! 這行代碼來(lái)說(shuō),它分為3的步驟,包括:讀取canread值,修改canread值,寫(xiě)回canread的值。 但是不要忘記了,我們的linux系統(tǒng)是一個(gè)多任務(wù)的系統(tǒng),假如當(dāng)A讀取了canread的值為1時(shí),還沒(méi)來(lái)得及減1,就已經(jīng)切換到了進(jìn)程B,進(jìn)程B讀出的canread的值也是1,這樣的話(huà),B就成功打開(kāi)了設(shè)備文件。如果這時(shí)再切換回了A,因?yàn)橹癆已經(jīng)讀出了canread為1,這時(shí)會(huì)將canread當(dāng)作1來(lái)進(jìn)行后續(xù)處理,也可以打開(kāi)文件。這可不是我們想要的,那么有沒(méi)有其他辦法呢?答案是肯定的,下面來(lái)介紹兩種方法:
方法一:原子操作 定義:原子操作指的是在執(zhí)行過(guò)程中不會(huì)被別的代碼路徑所中斷的操作。 下面是幾個(gè)常用原子操作函數(shù): atomic_t v = ATOMIC_INIT(0); ? ? //定義原子變量v并初始化為0 atomic_read(atomic_t *v); ? ? ? ?//返回原子變量的值 void atomic_inc(atomic_t *v); ? ?//原子變量增加1 void atomic_dec(atomic_t *v); ? ?//原子變量減少1 int atomic_dec_and_test(atomic_t *v); //自減操作后測(cè)試其是否為0,為0則返回true,否則返回false。 修改代碼:
首先定義全局原子變量: static atomic_t canread= ATOMIC_INIT(1); 然后在open函數(shù)開(kāi)始處加入如下代碼: ?if(!atomic_dec_and_test(&canread)) ? ? ? ? { ? ? ? ? ?? ? ? ? ? ? ? atomic_inc(&canread); ? ? ? ? ? ? return -EBUSY; ? ? ? ? }
在close函數(shù)里面加入如下代碼: atomic_inc(&canread);
方法二:信號(hào)量 定義:信號(hào)量(semaphore)是用于保護(hù)臨界區(qū)的一種常用方法,只有得到信號(hào)量的進(jìn)程才能執(zhí)行臨界區(qū)代碼。當(dāng)獲取不到信號(hào)量時(shí),進(jìn)程進(jìn)入休眠等待狀態(tài)。 下面是幾個(gè)常用的信號(hào)量相關(guān)的函數(shù):
2. 信號(hào)量 信號(hào)量(semaphore)是用于保護(hù)臨界區(qū)的一種常用方法,只有得到信號(hào)量的進(jìn)程才能執(zhí)行臨界區(qū)代碼。 當(dāng)獲取不到信號(hào)量時(shí),進(jìn)程進(jìn)入休眠等待狀態(tài)。 定義信號(hào)量 struct semaphore sem; 初始化信號(hào)量 void sema_init (struct semaphore *sem, int val); void init_MUTEX(struct semaphore *sem);//初始化為0 static DECLARE_MUTEX(button_lock);?? ? //定義互斥鎖 獲得信號(hào)量 void down(struct semaphore * sem); int down_interruptible(struct semaphore * sem);? int down_trylock(struct semaphore * sem); 釋放信號(hào)量 void up(struct semaphore * sem); 修改代碼: 首先定義全局互斥鎖: static DECLARE_MUTEX(button_lock); 在open函數(shù)中獲得信號(hào)量: down(&button_lock); 在close函數(shù)中釋放信號(hào)量:
up(&button_lock); 我們測(cè)試時(shí)第一次運(yùn)行應(yīng)用程序,發(fā)現(xiàn)其狀態(tài)時(shí)S,第二次運(yùn)行,其狀態(tài)時(shí)D,S表示睡眠狀態(tài),是因?yàn)闆](méi)有按鍵按下而產(chǎn)生睡眠,而D表示一種僵死狀態(tài),或者也可以說(shuō)是一種睡眠狀態(tài),不過(guò)它是因?yàn)闆](méi)有獲取信號(hào)量而進(jìn)入僵死。那么第二個(gè)進(jìn)程什么時(shí)候才能從僵死狀 態(tài)喚醒呢?那就要等到第一個(gè)進(jìn)程釋放信號(hào)量。我們將第一個(gè)進(jìn)程殺死,發(fā)現(xiàn)第二個(gè)進(jìn)程的狀態(tài)變成了S,從而驗(yàn)證了我們的說(shuō)法。
下面我們?cè)賮?lái)談一下阻塞和非阻塞的問(wèn)題: 阻塞操作:是指在執(zhí)行設(shè)備操作時(shí)若不能獲得資源則掛起進(jìn)程,直到滿(mǎn)足可操作的條件后再進(jìn)行操作。被掛起的進(jìn)程進(jìn)入休眠狀態(tài),被從調(diào)度器的運(yùn)行隊(duì)列移走,直到等待的條件被滿(mǎn)足。 非阻塞操作:進(jìn)程在不能進(jìn)行設(shè)備操作時(shí)并不掛起,它或者放棄,或者不停地查詢(xún),直至可以進(jìn)行操作為止。 我們?cè)隍?qū)動(dòng)程序中修改代碼: 在open函數(shù)中加入如下代碼: if (file->f_flags & O_NONBLOCK) { if (down_trylock(&button_lock)) return -EBUSY; } else { down(&button_lock); } 我們?cè)趓ead函數(shù)中加入如下代碼: if (filp->f_flags & O_NONBLOCK) { if (!ev_press) ?//如果沒(méi)有按鍵按下返回 return -EAGAIN; } else { wait_event_interruptible(button_waitq, ev_press);//這一句要將本來(lái)的注釋掉 } 將ev_press相關(guān)的定義添加上 添加定義:static DECLARE_WAIT_QUEUE_HEAD(button_waitq); 在中斷中補(bǔ)上這一句:wake_up_interruptible(&button_waitq);
測(cè)試程序如下: #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> #include <poll.h> #include <signal.h> #include <sys/types.h> #include <unistd.h> #include <fcntl.h>
int main(int argc, char **argv) { ? ? ? ? int fd; ? ?? unsigned char key_val; ? ? ? fd = open("/dev/keys", O_RDWR); if (fd < 0) { printf("can't open!\n"); }
while (1) { ?? ?read(fd, &key_val, 1); ?? ?printf("key_val: 0x%x\n", key_val); } return 0; } 默認(rèn)情況下是阻塞方式打開(kāi)的,運(yùn)行測(cè)試程序,當(dāng)我們沒(méi)有按下按鍵時(shí)會(huì)休眠,但不會(huì)返回。 我們將: fd = open("/dev/keys", O_RDWR);改為 fd = open("/dev/keys", O_RDWR |?O_NONBLOCK); 會(huì)變成非阻塞方式打開(kāi),這時(shí)沒(méi)有按鍵按下會(huì)返回。為方便測(cè)試,我們?cè)谘h(huán)里加入:sleep(5);

總結(jié)

以上是生活随笔為你收集整理的字符设备驱动程序之按键——同步互斥阻塞的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 中文字幕乱码人妻一区二区三区 | 午夜精品久久久久久久爽 | 亚洲欧美成人网 | 香蕉视频1024 | 黑人超碰 | 黄色国产视频网站 | 亚洲激情三区 | 依依激情网 | 精品免费一区二区三区 | 国产在线免费 | 日韩黄片一区二区三区 | 国产毛片久久久久久久 | 少妇综合| 成人在线一区二区 | 日韩理论片在线观看 | sm捆绑调教视频 | av在线第一页 | 日韩在线中文字幕视频 | 密臀av一区二区 | 午夜婷婷网 | 亚洲人成电影在线播放 | 亚洲尤物视频 | 骚鸭av| 亚洲高清视频在线观看 | 天堂一区在线观看 | 国产v片 | 天天天天操| 在线欧美色 | 免费看一区二区三区 | 日韩大片在线免费观看 | 亚洲成人系列 | 欧美色亚洲 | 偷拍欧美另类 | 先锋av资源网站 | 日韩黄色精品 | 噼里啪啦动漫高清在线观看 | 国产精品亚洲第一 | 国产性猛交xx乱 | 人人精品久久 | 成人h动漫精品一区二区无码 | 人人插人人草 | 91精品国产综合久久久蜜臀 | 五月婷在线观看 | 日本后进式猛烈xx00动态图 | 97超在线| 麻豆国产原创 | av噜噜噜 | 一本色道久久综合狠狠躁的推荐 | 一级黄色特级片 | 欧美日本国产在线 | 岳乳丰满一区二区三区 | 亚洲国产精品久久久久爰色欲 | 人人草人人澡 | 少妇真实被内射视频三四区 | 日韩一级在线观看 | 天堂伊人网 | 日本乱码视频 | 久久成人18免费观看 | 免费观看一区二区三区毛片 | 久久久久久999 | 添女人荫蒂视频 | 中文字幕看片 | 成人精品三级av在线看 | 免费麻豆 | www一级片 | 逼逼av| 香蕉尹人 | 丰满少妇一区二区 | 日韩在线视频二区 | 免费一级片在线观看 | 污污网站免费在线观看 | 天堂视频在线观看免费 | 久久久久久18 | 毛片视频软件 | 国产波霸爆乳一区二区 | 黄色av影院| 国产精品美女久久久久久久久 | 成人网在线 | 国产jzjzjz丝袜老师水多 | 爆乳2把你榨干哦ova在线观看 | 午夜精品久久久久久久无码 | 黄色片免费观看视频 | 麻豆成人精品 | 六月婷婷久久 | 女人18岁毛片 | 国产稀缺真实呦乱在线 | 91九色中文 | 国产人妻aⅴ色偷 | 国产一区二区黄 | 福利视频在线免费观看 | 日本爱爱免费视频 | 欧美成人三级 | 欧美日韩国产亚洲一区 | 懂色aⅴ一区二区三区免费 国产精品99在线观看 | 日本二区三区视频 | 优优色影院 | 级毛片| 午夜一区不卡 | 亚洲精品九九 |