成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

linux異步執(zhí)行命令 linux 異步讀寫文件

當(dāng)linux應(yīng)用程序中存在多個(gè)異步通知時(shí)怎樣處理

驅(qū)動(dòng)程序運(yùn)行在內(nèi)核空間中,應(yīng)用程序運(yùn)行在用戶空間中,兩者是不能直接通信的。但在實(shí)際應(yīng)用中,在設(shè)備已經(jīng)準(zhǔn)備好的時(shí)候,我們希望通知用戶程序設(shè)備已經(jīng)ok,用戶程序可以讀取了,這樣應(yīng)用程序就不需要一直查詢?cè)撛O(shè)備的狀態(tài),從而節(jié)約了資源,這就是異步通知。好,那下一個(gè)問(wèn)題就來(lái)了,這個(gè)過(guò)程如何實(shí)現(xiàn)呢?簡(jiǎn)單,兩方面的工作。

成都創(chuàng)新互聯(lián)堅(jiān)持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:成都做網(wǎng)站、成都網(wǎng)站制作、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時(shí)代的鯉城網(wǎng)站設(shè)計(jì)、移動(dòng)媒體設(shè)計(jì)的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!

一 驅(qū)動(dòng)方面:

1. 在設(shè)備抽象的數(shù)據(jù)結(jié)構(gòu)中增加一個(gè)struct fasync_struct的指針

2. 實(shí)現(xiàn)設(shè)備操作中的fasync函數(shù),這個(gè)函數(shù)很簡(jiǎn)單,其主體就是調(diào)用內(nèi)核的fasync_helper函數(shù)。

3. 在需要向用戶空間通知的地方(例如中斷中)調(diào)用內(nèi)核的kill_fasync函數(shù)。

4. 在驅(qū)動(dòng)的release方法中調(diào)用前面定義的fasync函數(shù)

呵呵,簡(jiǎn)單吧,就三點(diǎn)。其中fasync_helper和kill_fasync都是內(nèi)核函數(shù),我們只需要調(diào)用就可以了。在

1中定義的指針是一個(gè)重要參數(shù),fasync_helper和kill_fasync會(huì)使用這個(gè)參數(shù)。

二 應(yīng)用層方面

1. 利用signal或者sigaction設(shè)置SIGIO信號(hào)的處理函數(shù)

2. fcntl的F_SETOWN指令設(shè)置當(dāng)前進(jìn)程為設(shè)備文件owner

3. fcntl的F_SETFL指令設(shè)置FASYNC標(biāo)志

完成了以上友凱的工作的話,當(dāng)內(nèi)核執(zhí)行到kill_fasync函數(shù),用戶空間SIGIO函數(shù)的處理函數(shù)就會(huì)被調(diào)用了。

呵呵,看起來(lái)不是很復(fù)雜把,讓我們結(jié)合具體代碼看看就更明白了。

先從應(yīng)用層代碼開(kāi)始吧:

#include sys/types.h

#include sys/stat.h搏告坦

#include stdio.h

#include fcntl.h

#include signal.h

#include unistd.h

#define MAX_LEN 100

//處理函數(shù),沒(méi)什么好講的,用戶自己定義

void input_handler(int num)

{

char data[MAX_LEN];

int len;

//讀取并輸出STDIN_FILENO上的輸入

len = read(STDIN_FILENO, data, MAX_LEN);

data[len] = 0;

printf("input available:%s\n", data);

}

void main()

{

int oflags;

//啟動(dòng)信號(hào)驅(qū)動(dòng)機(jī)制,將SIGIO信號(hào)同input_handler函數(shù)關(guān)聯(lián)起來(lái),一旦產(chǎn)生SIGIO信號(hào),就會(huì)執(zhí)行input_handler

signal(SIGIO, input_handler);

//STDIN_FILENO是打開(kāi)的設(shè)備文件描述符,F_SETOWN用來(lái)決定操作是干什么的,getpid()是個(gè)系統(tǒng)調(diào)用,

//功能是返回當(dāng)前進(jìn)程的進(jìn)程號(hào),整個(gè)函數(shù)的功能是STDIN_FILENO設(shè)置這個(gè)設(shè)備文件的擁有者為當(dāng)前進(jìn)基桐程。

fcntl(STDIN_FILENO, F_SETOWN, getpid());

//得到打開(kāi)文件描述符的狀態(tài)

oflags = fcntl(STDIN_FILENO, F_GETFL);

//設(shè)置文件描述符的狀態(tài)為oflags | FASYNC屬性,一旦文件描述符被設(shè)置成具有FASYNC屬性的狀態(tài),

//也就是將設(shè)備文件切換到異步操作模式。這時(shí)系統(tǒng)就會(huì)自動(dòng)調(diào)用驅(qū)動(dòng)程序的fasync方法。

fcntl(STDIN_FILENO, F_SETFL, oflags | FASYNC);

//最后進(jìn)入一個(gè)死循環(huán),程序什么都不干了,只有信號(hào)能激發(fā)input_handler的運(yùn)行

//如果程序中沒(méi)有這個(gè)死循環(huán),會(huì)立即執(zhí)行完畢

while (1);

}

再看驅(qū)動(dòng)層代碼,驅(qū)動(dòng)層其他部分代碼不變,就是增加了一個(gè)fasync方法的實(shí)現(xiàn)以及一些改動(dòng)

//首先是定義一個(gè)結(jié)構(gòu)體,其實(shí)這個(gè)結(jié)構(gòu)體存放的是一個(gè)列表,這個(gè)

//列表保存的是一系列設(shè)備文件,SIGIO信號(hào)就發(fā)送到這些設(shè)備上

static struct fasync_struct *fasync_queue;

//fasync方法的實(shí)現(xiàn)

static int my_fasync(int fd, struct file * filp, int on)

{

int retval;

//將該設(shè)備登記到fasync_queue隊(duì)列中去

retval=fasync_helper(fd,filp,on,fasync_queue);

if(retval0)

{

return retval;

}

return 0;

}

在驅(qū)動(dòng)的release方法中我們?cè)僬{(diào)用my_fasync方法

int my_release(struct inode *inode, struct file *filp)

{

//..processing..

drm_fasync(-1, filp, 0);

//..processing..

}

這樣后我們?cè)谛枰牡胤剑ū热缰袛啵┱{(diào)用下面的代碼,就會(huì)向fasync_queue隊(duì)列里的設(shè)備發(fā)送SIGIO信號(hào)

,應(yīng)用程序收到信號(hào),執(zhí)行處理程序

if (fasync_queue)

kill_fasync(fasync_queue, SIGIO, POLL_IN);

好了,這下大家知道該怎么用異步通知機(jī)制了吧?

以下是幾點(diǎn)說(shuō)明[1]:

1 兩個(gè)函數(shù)的原型

int fasync_helper(struct inode *inode, struct file *filp, int mode, struct fasync_struct **fa);

一個(gè)"幫忙者", 來(lái)實(shí)現(xiàn) fasync 設(shè)備方法. mode 參數(shù)是傳遞給方法的相同的值, 而 fa 指針指向一個(gè)設(shè)

備特定的 fasync_struct *

void kill_fasync(struct fasync_struct *fa, int sig, int band);

如果這個(gè)驅(qū)動(dòng)支持異步通知, 這個(gè)函數(shù)可用來(lái)發(fā)送一個(gè)信號(hào)到登記在 fa 中的進(jìn)程.

2.

fasync_helper 用來(lái)向等待異步信號(hào)的設(shè)備鏈表中添加或者刪除設(shè)備文件, kill_fasync被用來(lái)通知擁有相關(guān)設(shè)備的進(jìn)程. 它的參數(shù)是被傳遞的信號(hào)(常常是 SIGIO)和 band, 這幾乎都是 POLL_IN[25](但是這可用來(lái)發(fā)送"緊急"或者帶外數(shù)據(jù), 在網(wǎng)絡(luò)代碼里).

linux驅(qū)動(dòng)模塊中添加異步通知機(jī)制需要完成哪些工作

一 驅(qū)動(dòng)方面:

1. 在設(shè)備抽象的數(shù)據(jù)結(jié)構(gòu)中增加一個(gè)struct fasync_struct的指針

2. 實(shí)現(xiàn)設(shè)備操作中的fasync函數(shù),這個(gè)函數(shù)很簡(jiǎn)單,其主體就是調(diào)用內(nèi)嘩型核的fasync_helper函數(shù)。

3. 在需要向用戶空間通知的地方(例如中斷中)調(diào)用內(nèi)核的kill_fasync函數(shù)。

4. 在驅(qū)動(dòng)的release方法中調(diào)用前面定義的fasync函數(shù)

呵呵,簡(jiǎn)單吧,就三點(diǎn)。其中fasync_helper和kill_fasync都是內(nèi)核函數(shù),我們只需要調(diào)用就可以了。在1中定義的指針是一個(gè)重要參數(shù),fasync_helper和kill_fasync會(huì)使用這個(gè)參數(shù)。

二 應(yīng)用層方面

1. 利用signal或者sigaction設(shè)置SIGIO信號(hào)的處理函數(shù)

2. fcntl的F_SETOWN指令設(shè)置當(dāng)前進(jìn)程為設(shè)備文件owner

3. fcntl的F_SETFL指令設(shè)置FASYNC標(biāo)志

完成了以上的工作的話,當(dāng)內(nèi)核執(zhí)行到kill_fasync函數(shù),用戶空間SIGIO函數(shù)的處理函數(shù)就會(huì)被調(diào)用了。

呵呵,看起來(lái)不是很復(fù)雜把,讓我們結(jié)合具體代碼看看就更明白了。

先從應(yīng)用層代碼開(kāi)始吧:

#include sys/types.h

#include sys/stat.h

#include stdio.h

#include fcntl.h

#include signal.h

#include unistd.h

#define MAX_LEN 100

//處理函數(shù),沒(méi)什么好講的,用戶自己定義

void input_handler(int num)

{

char data[MAX_LEN];

int len;

//讀取并輸出STDIN_FILENO上的輸入

len = read(STDIN_FILENO, data, MAX_LEN);

data[len] = 0;

printf("input available:%s\n", data);

}

void main()

{

int oflags;

//啟動(dòng)信號(hào)驅(qū)動(dòng)機(jī)制,將SIGIO信號(hào)同input_handler函數(shù)關(guān)聯(lián)起來(lái),一旦產(chǎn)生SIGIO信號(hào),就會(huì)執(zhí)行input_handler

signal(SIGIO, input_handler);

//STDIN_FILENO是打開(kāi)的設(shè)備文件描述符,F_SETOWN用來(lái)決定操作是干什么的,getpid()是個(gè)系統(tǒng)調(diào)用,

//功能是返回當(dāng)前進(jìn)程的進(jìn)程號(hào),整個(gè)函數(shù)的功能是STDIN_FILENO設(shè)置這個(gè)設(shè)備文件的擁有者為當(dāng)前進(jìn)程。

fcntl(STDIN_FILENO, F_SETOWN, getpid());

//得到打開(kāi)文件描述符的狀態(tài)

oflags = fcntl(STDIN_FILENO, F_GETFL);

//設(shè)茄蘆粗置文件描述符的狀態(tài)為oflags | FASYNC屬性,一旦文件描述符被設(shè)置成具有FASYNC屬性的狀態(tài),

//也就是將設(shè)備文件切換到異步操作模式。這時(shí)系統(tǒng)就會(huì)自動(dòng)調(diào)用驅(qū)動(dòng)程序的fasync方法。

fcntl(STDIN_FILENO, F_SETFL, oflags | FASYNC);

//最后進(jìn)顫鎮(zhèn)入一個(gè)死循環(huán),程序什么都不干了,只有信號(hào)能激發(fā)input_handler的運(yùn)行

//如果程序中沒(méi)有這個(gè)死循環(huán),會(huì)立即執(zhí)行完畢

while (1);

}

再看驅(qū)動(dòng)層代碼,驅(qū)動(dòng)層其他部分代碼不變,就是增加了一個(gè)fasync方法的實(shí)現(xiàn)以及一些改動(dòng)

//首先是定義一個(gè)結(jié)構(gòu)體,其實(shí)這個(gè)結(jié)構(gòu)體存放的是一個(gè)列表,這個(gè)

//列表保存的是一系列設(shè)備文件,SIGIO信號(hào)就發(fā)送到這些設(shè)備上

static struct fasync_struct *fasync_queue;

//fasync方法的實(shí)現(xiàn)

static int my_fasync(int fd, struct file * filp, int on)

{

int retval;

//將該設(shè)備登記到fasync_queue隊(duì)列中去

retval=fasync_helper(fd,filp,on,fasync_queue);

if(retval0)

{

return retval;

}

return 0;

}

在驅(qū)動(dòng)的release方法中我們?cè)僬{(diào)用my_fasync方法

int my_release(struct inode *inode, struct file *filp)

{

//..processing..

drm_fasync(-1, filp, 0);

//..processing..

}這樣后我們?cè)谛枰牡胤剑ū热缰袛啵┱{(diào)用下面的代碼,就會(huì)向fasync_queue隊(duì)列里的設(shè)備發(fā)送SIGIO信號(hào)

,應(yīng)用程序收到信號(hào),執(zhí)行處理程序

if (fasync_queue)

kill_fasync(fasync_queue, SIGIO, POLL_IN);

Runtime.getRuntime().exec(cmd) 在linux下調(diào)用shell,是異步執(zhí)行嗎。

可以調(diào)用shell 中命游行令測(cè)碰磨喚笑凱試

sleep?600??//單位秒

Linux異步IO

Linux中最常用的IO模型是同步IO,在這個(gè)模型中,當(dāng)請(qǐng)求發(fā)出之后,應(yīng)用程序就會(huì)阻塞,直到請(qǐng)求滿足條件為止。這是一種很好的解決方案,調(diào)用應(yīng)用程序在等待IO完成的時(shí)候不需要占用CPU,但是在很多場(chǎng)景中,IO請(qǐng)求可能需要和CPU消耗交疊,以充分利用CPU和IO提高吞吐率。

下圖描繪了異步IO的時(shí)序,應(yīng)用程序發(fā)起IO操作后,直接開(kāi)始執(zhí)行,并不等待IO結(jié)束,它要么過(guò)一段時(shí)間來(lái)查詢之前的IO請(qǐng)求完成情況,要么IO請(qǐng)求差襲正完成了會(huì)自動(dòng)被調(diào)用與IO完成綁定的回調(diào)函數(shù)。

Linux的AIO有多種實(shí)現(xiàn),其中一種實(shí)現(xiàn)是在用戶空間的glibc庫(kù)中實(shí)現(xiàn)的,本質(zhì)上是借用了多線程模型,用開(kāi)啟的新的線程以同步的方式做IO,新的AIO輔助線程與發(fā)起AIO的線程以pthread_cond_signal()的形式進(jìn)行線程間的同步,glibc的AIO主要包含以下函數(shù):

1、aio_read()

aio_read()函數(shù)請(qǐng)求對(duì)一個(gè)有效的文件描述符進(jìn)行異步讀操作。這個(gè)文件描述符可以代表一個(gè)文件、套接字,甚至管道,aio_read()函禪迅數(shù)原型如下:

aio_read()函數(shù)在請(qǐng)求進(jìn)行排隊(duì)之后就會(huì)立即返回(盡管讀操作并未完成),如果執(zhí)行成功就返回0,如果出現(xiàn)錯(cuò)誤就返回-1。參數(shù)aiocb(AIO I/O Control Block)結(jié)構(gòu)體包含了傳輸?shù)乃行畔?,以及為AIO操作準(zhǔn)備的用戶虛悔空間緩沖區(qū)。在產(chǎn)生IO完成通知時(shí),aiocb結(jié)構(gòu)就被用來(lái)唯一標(biāo)識(shí)所完成的IO操作。

2.aio_write()

aio_write()函數(shù)用來(lái)請(qǐng)求一個(gè)異步寫操作。函數(shù)原型如下:

aio_write()函數(shù)會(huì)立即返回,并且它的請(qǐng)求以及被排隊(duì)(成功時(shí)返回值為0,失敗時(shí)返回值為-1)

3.aio_error()

aio_error()函數(shù)被用來(lái)確定請(qǐng)求的狀態(tài),其原型如下:

該函數(shù)的返回:

4.aio_return()

異步IO和同步阻塞IO方式之間有一個(gè)區(qū)別就是不能立即訪問(wèn)函數(shù)的返回狀態(tài),因?yàn)楫惒絀O沒(méi)有阻塞在read()調(diào)用上。在標(biāo)準(zhǔn)的同步阻塞read()調(diào)用中,返回狀態(tài)是在該函數(shù)返回時(shí)提供的。

但是在異步IO中,我們要用aio_return()函數(shù),原型如下:

只有在aio_error()調(diào)用確定請(qǐng)求已經(jīng)完成(可能成功、也可能發(fā)生了錯(cuò)誤)之后,才會(huì)調(diào)用這個(gè)函數(shù),aio_return()的返回值就等價(jià)于同步情況中read()或者write系統(tǒng)調(diào)用的返回值。

5.aio_suspend()

用戶可以用該函數(shù)阻塞調(diào)用進(jìn)程,直到異步請(qǐng)求完成為止,調(diào)用者提供了一個(gè)aiocb引用列表,其中任何一個(gè)完成都會(huì)導(dǎo)致aio_suspend()返回。函數(shù)原型如下:

6.aio_cancel()

該函數(shù)允許用戶取消對(duì)某個(gè)文件描述符執(zhí)行的一個(gè)或所以IO請(qǐng)求。

要取消一個(gè)請(qǐng)求,用戶需要提供文件描述符和aiocb指針,如果這個(gè)請(qǐng)求被成功取消了,那么這個(gè)函數(shù)就會(huì)返回AIO_CANCELED。如果請(qǐng)求完成了,就會(huì)返回AIO_NOTCANCELED。

7.lio_listio()

lio_listio()函數(shù)可用于同時(shí)發(fā)起多個(gè)傳輸。這個(gè)函數(shù)非常重要,它使得用戶可以在一個(gè)系統(tǒng)調(diào)用中啟動(dòng)大量的IO操作,原型如下:

mode參數(shù)可以是LIO_WAIT或者是LIO_NOWAIT。LIO_WAIT會(huì)阻塞這個(gè)調(diào)用,直到所有的IO都返回為止,若是LIO_NOWAIT模型,在IO操作完成排隊(duì)之后,該函數(shù)就會(huì)返回。list是一個(gè)aiocb的列表,最大元素的個(gè)數(shù)是由nent定義的。如果list的元素為null,lio_listio()會(huì)將其忽略。

本文題目:linux異步執(zhí)行命令 linux 異步讀寫文件
文章源于:http://jinyejixie.com/article8/ddpijop.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供標(biāo)簽優(yōu)化、響應(yīng)式網(wǎng)站網(wǎng)站設(shè)計(jì)、做網(wǎng)站品牌網(wǎng)站設(shè)計(jì)、網(wǎng)站維護(hù)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

營(yíng)銷型網(wǎng)站建設(shè)
磐安县| 称多县| 特克斯县| 平潭县| 博兴县| 电白县| 古丈县| 浦城县| 浏阳市| 浦城县| 娄烦县| 临西县| 临颍县| 抚松县| 都兰县| 宝山区| 琼海市| 伊春市| 大埔县| 花莲县| 姜堰市| 辰溪县| 渭南市| 青州市| 南漳县| 长武县| 辽源市| 滕州市| 安阳市| 灵川县| 深圳市| 灵山县| 苍溪县| 信宜市| 东源县| 滨州市| 崇明县| 高台县| 博湖县| 古丈县| 朝阳市|