導航:首頁 > 操作系統 > linux的非同步機制

linux的非同步機制

發布時間:2022-06-01 12:51:19

linux驅動模塊中添加非同步通知機制需要完成哪些工作

一 驅動方面:
1. 在設備抽象的數據結構中增加一個struct fasync_struct的指針
2. 實現設備操作中的fasync函數,這個函數很簡單,其主體就是調用內核的fasync_helper函數。
3. 在需要向用戶空間通知的地方(例如中斷中)調用內核的kill_fasync函數。
4. 在驅動的release方法中調用前面定義的fasync函數
呵呵,簡單吧,就三點。其中fasync_helper和kill_fasync都是內核函數,我們只需要調用就可以了。在1中定義的指針是一個重要參數,fasync_helper和kill_fasync會使用這個參數。

二 應用層方面
1. 利用signal或者sigaction設置SIGIO信號的處理函數
2. fcntl的F_SETOWN指令設置當前進程為設備文件owner
3. fcntl的F_SETFL指令設置FASYNC標志
完成了以上的工作的話,當內核執行到kill_fasync函數,用戶空間SIGIO函數的處理函數就會被調用了。
呵呵,看起來不是很復雜把,讓我們結合具體代碼看看就更明白了。
先從應用層代碼開始吧:

#include <sys/types.h>

#include <sys/stat.h>

#include <stdio.h>

#include <fcntl.h>

#include <signal.h>

#include <unistd.h>

#define MAX_LEN 100

//處理函數,沒什麼好講的,用戶自己定義

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;

//啟動信號驅動機制,將SIGIO信號同input_handler函數關聯起來,一旦產生SIGIO信號,就會執行input_handler

signal(SIGIO, input_handler);

//STDIN_FILENO是打開的設備文件描述符,F_SETOWN用來決定操作是干什麼的,getpid()是個系統調用,

//功能是返回當前進程的進程號,整個函數的功能是STDIN_FILENO設置這個設備文件的擁有者為當前進程。
fcntl(STDIN_FILENO, F_SETOWN, getpid());

//得到打開文件描述符的狀態

oflags = fcntl(STDIN_FILENO, F_GETFL);

//設置文件描述符的狀態為oflags | FASYNC屬性,一旦文件描述符被設置成具有FASYNC屬性的狀態,
//也就是將設備文件切換到非同步操作模式。這時系統就會自動調用驅動程序的fasync方法。
fcntl(STDIN_FILENO, F_SETFL, oflags | FASYNC);

//最後進入一個死循環,程序什麼都不幹了,只有信號能激發input_handler的運行

//如果程序中沒有這個死循環,會立即執行完畢
while (1);
}
再看驅動層代碼,驅動層其他部分代碼不變,就是增加了一個fasync方法的實現以及一些改動

//首先是定義一個結構體,其實這個結構體存放的是一個列表,這個

//列表保存的是一系列設備文件,SIGIO信號就發送到這些設備上
static struct fasync_struct *fasync_queue;

//fasync方法的實現
static int my_fasync(int fd, struct file * filp, int on)

{

int retval;
//將該設備登記到fasync_queue隊列中去

retval=fasync_helper(fd,filp,on,&fasync_queue);
if(retval<0)

{
return retval;

}
return 0;

}
在驅動的release方法中我們再調用my_fasync方法

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

{

//..processing..

drm_fasync(-1, filp, 0);

//..processing..
}這樣後我們在需要的地方(比如中斷)調用下面的代碼,就會向fasync_queue隊列里的設備發送SIGIO信號
,應用程序收到信號,執行處理程序
if (fasync_queue)
kill_fasync(&fasync_queue, SIGIO, POLL_IN);

② 當linux應用程序中存在多個非同步通知時怎樣處理

驅動程序運行在內核空間中,應用程序運行在用戶空間中,兩者是不能直接通信的。但在實際應用中,在設備已經准備好的時候,我們希望通知用戶程序設備已經ok,用戶程序可以讀取了,這樣應用程序就不需要一直查詢該設備的狀態,從而節約了資源,這就是非同步通知。好,那下一個問題就來了,這個過程如何實現呢?簡單,兩方面的工作。

一 驅動方面:
1. 在設備抽象的數據結構中增加一個struct fasync_struct的指針
2. 實現設備操作中的fasync函數,這個函數很簡單,其主體就是調用內核的fasync_helper函數。
3. 在需要向用戶空間通知的地方(例如中斷中)調用內核的kill_fasync函數。
4. 在驅動的release方法中調用前面定義的fasync函數
呵呵,簡單吧,就三點。其中fasync_helper和kill_fasync都是內核函數,我們只需要調用就可以了。在
1中定義的指針是一個重要參數,fasync_helper和kill_fasync會使用這個參數。

二 應用層方面
1. 利用signal或者sigaction設置SIGIO信號的處理函數
2. fcntl的F_SETOWN指令設置當前進程為設備文件owner
3. fcntl的F_SETFL指令設置FASYNC標志
完成了以上的工作的話,當內核執行到kill_fasync函數,用戶空間SIGIO函數的處理函數就會被調用了。
呵呵,看起來不是很復雜把,讓我們結合具體代碼看看就更明白了。
先從應用層代碼開始吧:
#include <sys/types.h>

#include <sys/stat.h>

#include <stdio.h>

#include <fcntl.h>

#include <signal.h>

#include <unistd.h>

#define MAX_LEN 100

//處理函數,沒什麼好講的,用戶自己定義

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;

//啟動信號驅動機制,將SIGIO信號同input_handler函數關聯起來,一旦產生SIGIO信號,就會執行input_handler

signal(SIGIO, input_handler);

//STDIN_FILENO是打開的設備文件描述符,F_SETOWN用來決定操作是干什麼的,getpid()是個系統調用,

//功能是返回當前進程的進程號,整個函數的功能是STDIN_FILENO設置這個設備文件的擁有者為當前進程。
fcntl(STDIN_FILENO, F_SETOWN, getpid());

//得到打開文件描述符的狀態

oflags = fcntl(STDIN_FILENO, F_GETFL);

//設置文件描述符的狀態為oflags | FASYNC屬性,一旦文件描述符被設置成具有FASYNC屬性的狀態,
//也就是將設備文件切換到非同步操作模式。這時系統就會自動調用驅動程序的fasync方法。
fcntl(STDIN_FILENO, F_SETFL, oflags | FASYNC);

//最後進入一個死循環,程序什麼都不幹了,只有信號能激發input_handler的運行

//如果程序中沒有這個死循環,會立即執行完畢
while (1);
}
再看驅動層代碼,驅動層其他部分代碼不變,就是增加了一個fasync方法的實現以及一些改動
//首先是定義一個結構體,其實這個結構體存放的是一個列表,這個

//列表保存的是一系列設備文件,SIGIO信號就發送到這些設備上
static struct fasync_struct *fasync_queue;

//fasync方法的實現
static int my_fasync(int fd, struct file * filp, int on)

{

int retval;
//將該設備登記到fasync_queue隊列中去

retval=fasync_helper(fd,filp,on,&fasync_queue);
if(retval<0)

{
return retval;

}
return 0;

}
在驅動的release方法中我們再調用my_fasync方法
int my_release(struct inode *inode, struct file *filp)

{

//..processing..

drm_fasync(-1, filp, 0);

//..processing..
}
這樣後我們在需要的地方(比如中斷)調用下面的代碼,就會向fasync_queue隊列里的設備發送SIGIO信號
,應用程序收到信號,執行處理程序
if (fasync_queue)
kill_fasync(&fasync_queue, SIGIO, POLL_IN);
好了,這下大家知道該怎麼用非同步通知機制了吧?

以下是幾點說明[1]:
1 兩個函數的原型
int fasync_helper(struct inode *inode, struct file *filp, int mode, struct fasync_struct **fa);
一個"幫忙者", 來實現 fasync 設備方法. mode 參數是傳遞給方法的相同的值, 而 fa 指針指向一個設
備特定的 fasync_struct *

void kill_fasync(struct fasync_struct *fa, int sig, int band);
如果這個驅動支持非同步通知, 這個函數可用來發送一個信號到登記在 fa 中的進程.

2.
fasync_helper 用來向等待非同步信號的設備鏈表中添加或者刪除設備文件, kill_fasync被用來通知擁有相關設備的進程. 它的參數是被傳遞的信號(常常是 SIGIO)和 band, 這幾乎都是 POLL_IN[25](但是這可用來發送"緊急"或者帶外數據, 在網路代碼里).

③ Linux開發需要什麼呢需要具備什麼基礎呢

一、linux和os:

1、命令netstat tcpmp ipcs ipcrm 這四個命令的熟練掌握程度基本上能體現實際開發和調試程序的經驗

2、cpu 內存 硬碟 等等與系統性能調試相關的命令必須熟練掌握,設置修改許可權 tcp網路狀態查看 各進程狀態 抓包相關等相關命令 必須熟練掌握

3、awk sed需掌握

4、共享內存的使用實現原理、然後共享內存段被映射進進程空間之後,存在於進程空間的什麼位置?共享內存段最大限制是多少?

5、c++進程內存空間分布(注意各部分的內存地址誰高誰低,注意棧從高道低分配,堆從低到高分配)

6、ELF是什麼?其大小與程序中全局變數的是否初始化有什麼關系(注意.bss段)

7、使用過哪些進程間通訊機制,並詳細說明

8、makefile編寫,雖然比較基礎,但是會被問到

9、gdb調試相關的經驗,會被問到

10、如何定位內存泄露?

11、動態鏈接和靜態鏈接的區別

12、32位系統一個進程最多多少堆內存

13、多線程和多進程的區別(重點 必須從cpu調度,上下文切換,數據共享,多核cup利用率,資源佔用,等等各方面回答,然後有一個問題必須會被問到:哪些東西是一個線程私有的?答案中必須包含寄存器,否則悲催)

14、寫一個c程序辨別系統是64位 or 32位

15、寫一個c程序辨別系統是大端or小端位元組序

16、信號:列出常見的信號,信號怎麼處理?

17、i++是否原子操作?並解釋為什麼???????

18、說出你所知道的各類linux系統的各類同步機制(重點),什麼是死鎖?如何避免死鎖(每個技術面試官必問)

19、列舉說明linux系統的各類非同步機制

20、exit() _exit()的區別?

21、如何實現守護進程?

22、linux的內存管理機制是什麼?

23、linux的任務調度機制是什麼?

24、標准庫函數和系統調用的區別?

25、補充一個問題:系統如何將一個信號通知到進程?

二、c語言:

1、宏定義和展開(必須精通)

2、位操作(必須精通)

3、指針操作和計算(必須精通)

4、內存分配(必須精通)

5、各類庫函數必須非常熟練的實現

6、哪些庫函數屬於高危函數,為什麼?(strcpy等等)

三、c++:

1、一個String類的完整實現必須很快速寫出來(注意:賦值構造,operator=是關鍵)

2、虛函數的作用和實現原理(必問必考,實現原理必須很熟)

3、sizeof一個類求大小(注意成員變數,函數,虛函數,繼承等等對大小的影響)

4、指針和引用的區別(一般都會問到)

5、多重類構造和析構的順序

6、stl各容器的實現原理(必考)

7、extern c 是幹啥的,(必須將編譯器的函數名修飾的機制解答的很透徹)

8、volatile是幹啥用的,(必須將cpu的寄存器緩存機制回答的很透徹)

9、static const等等的用法,(能說出越多越好)

四、數據結構或者演算法

1、《離散數學》范圍內的一切問題皆由可能被深入問到(最重要,最體現功底,最能加分,特別是各類樹結構的實現和應用)

2、各類排序:大根堆的實現,快排(如何避免最糟糕的狀態?),bitmap的運用等等

3、hash, 任何一個技術面試官必問(例如為什麼一般hashtable的桶數會取一個素數?如何有效避免hash結果值的碰撞)

五、網路編程

1、tcp與udp的區別(必問)

2、udp調用connect有什麼作用?

3、tcp連接中時序圖,狀態圖,必須非常非常熟練

4、socket服務端的實現,select和epoll的區別(必問)

5、epoll哪些觸發模式,有啥區別?(必須非常詳盡的解釋水平觸發和邊緣觸發的區別,以及邊緣觸發在編程中要做哪些更多的確認)

6、大規模連接上來,並發模型怎麼設計

7、tcp結束連接怎麼握手,time_wait狀態是什麼,為什麼會有time_wait狀態?哪一方會有time_wait狀態,如何避免time_wait狀態佔用資源(必須回答的詳細)

8、tcp頭多少位元組?哪些欄位?(必問)

9、什麼是滑動窗口(必問)

10、connect會阻塞,怎麼解決?(必考必問,提示:設置非阻塞,返回之後用select檢測狀態)

11、如果select返回可讀,結果只讀到0位元組,什麼情況?

12、keepalive 是什麼東東?如何使用?

13、列舉你所知道的tcp選項,並說明其作用。

14、socket什麼情況下可讀?

六、db:

1、mysql,會考sql語言,伺服器資料庫大規模數據怎麼設計,db各種性能指標

④ linux同步io和非同步io的區別

非同步文件IO也就是重疊IO。
在同步文件IO中,線程啟動一個IO操作然後就立即進入等待狀態,直到IO操作完成後才醒來繼續執行。而非同步文件IO方式中,線程發送一個IO請求到內核,然後繼續處理其他的事情,內核完成IO請求後,將會通知線程IO操作完成了。
如果IO請求需要大量時間執行的話,非同步文件IO方式可以顯著提高效率,因為在線程等待的這段時間內,CPU將會調度其他線程進行執行,如果沒有其他線程需要執行的話,這段時間將會浪費掉(可能會調度操作系統的零頁線程)。如果IO請求操作很快,用非同步IO方式反而還低效,還不如用同步IO方式。
同步IO在同一時刻只允許一個IO操作,也就是說對於同一個文件句柄的IO操作是序列化的,即使使用兩個線程也不能同時對同一個文件句柄同時發出讀寫操作。重疊IO允許一個或多個線程同時發出IO請求。

⑤ 請問linux下C編程多線程同步和非同步的區別,如何能實現程序的同步和非同步編程

同步就是使得兩個或者多個進程之間的行為按照一定的時序來執行。比如說線程A完成了某件事,然後線程B才能做某件事。具體一點,就是,線程間的某個動作執行前需要確認一個或者多個其他線程的當前狀態。而非同步則是多個線程各跑各的,互不幹涉。

Linux下的多線程實現由pthread庫提供,頭文件為pthread.h。多線程最重要的就是要保護好共享資源(用互斥體,mutex),尤其是非同步。代碼哥哥就不上了,這里關鍵的不是代碼的問題,也不是Linux、Windows的問題,重要的是概念的理解。哥們不妨先研究研究「生產者-消費者」這個常出現在教科書上的模型,這是一個典型的同步問題。就講這么多了,拜拜。

⑥ 簡單說明+Linux+系統中信號的處理方式。+(說出一種給1分舉例說明再加2分)

摘要 遇到問題一定要控制好自己的情緒,不要發火,不要偏激,不要說話太傷人,要懂得忍耐,忍耐不是為了讓你不去處理這件事情,而是為了避免在情緒失控的情況下,做出充動讓自己永遠後悔的事情。用心去體會,禮貌做人,踏實做事,放大格局,調整心態,把握當下,快樂生活每一天!謝謝!

⑦ Linux中同步信號和非同步信號分別怎麼解釋

Linux非同步信號
1.int pthread_kill(pthread_t threadid, intsigno);
向特定的線程發送信號signo
2.int pthread_sigmask(int how, const sigset_t*newmask, sigset_t *oldmask);
設置線程的信號屏蔽碼
3.int sigwait(const sigset_t *set, int *sig);
阻塞線程,等待set中指定的信號之一到達,並將到達的信號存入*sig。
4.代碼
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <signal.h>
//#define SIGUSRR 40;
int SIGUSRR = 40;
void* threadOne(void *arg)
{
sigset_tsigset;
intsigno;
sigemptyset(&sigset);
sigaddset(&sigset,SIGUSRR);
pthread_sigmask(SIG_BLOCK,&sigset, NULL);
while(1)
{
sigwait(&sigset,&signo);
printf("getthread cond sig!\n");
}
}
int main(int argc, char **argv)
{
if(argc != 1)
{
printf("Usage:\n");
printf("threadcond\n");
return1;
}
pthread_tthreadId;
if(pthread_create(&threadId,NULL, threadOne, NULL) != 0)
{
printf("threadcreate error! \n");
return1;
}
//structsigaction act;
//act.sa_handler=SIG_IGN;
//sigemptyset(&act.sa_mask);
//act.sa_flags=0;
//sigaction(SIGUSRR,&act,0);//設置信號SIGUSR1的處理方式忽略
usleep(1000000);
pthread_kill(threadId,SIGUSRR);
usleep(1000000);
pthread_kill(threadId,SIGUSRR);
usleep(2000000);
return0;
}

⑧ 在Linux中我還是理解不了同步和非同步,求解釋

打個比方,你現在要做兩件事,一件事是燒水,一件事是晾衣服。所謂的同步就是指:你必須等水燒開了再去晾衣服。所謂的非同步就是指在燒水的過程中,你完全可以再去晾衣服。所以,引入非同步機制其實就是為了提高效率。當然,有的時候,如果兩件事之間有依賴性,那麼就是無法非同步的,比如燒水和喝水,這兩件事是沒法非同步去做的。

⑨ 在設Linux在設備驅動和應用程序的非同步通知交互中,在設備驅動程序中增加信號釋放的作用是

在設備驅動和應用程序的非同步通知交互中,僅僅在應用程序端捕獲信號是不夠的,因為信號的源頭在設備驅動端。因此,應該在合適的時機讓設備驅動釋放信號,在設備驅動程序中增加信號釋放的相關代碼。為了使設備支持非同步通知機制,驅動程序中涉及3項工作。
1)支持F_SETOWN命令,能在這個控制命令處理中設置filp->f_owner為對應進程ID。不過此項工作已由內核完成,設備驅動無須處理。
2)支持F_SETFL命令的處理,每當FASYNC標志改變時,驅動程序中的fasync()函數將得以執行。因此,驅動中應該實現fasync()函數。
3)在設備資源可獲得時,調用kill_fasync()函數激發相應的信號。
驅動中的上述3項工作和應用程序中的3項工作是一一對應的,設備驅動中非同步通知編程比較簡單,主要用到一項數據結構和兩個函數。數據結構是fasync_struct結構體,兩個函數分別是:
1)處理FASYNC標志變更的函數。
int fasync_helper(int fd, struct file *filp, int mode, struct fasync_struct **fa);
2)釋放信號用的函數。
void kill_fasync(struct fasync_struct **fa, int sig, int band);
和其他的設備驅動一樣,將fasync_struct結構體指針放在設備結構體中仍然是最佳選擇。
在設備驅動的fasync()函數中,只需要簡單地將該函數的3個參數以及fasync_struct結構體指針的指針作為第4個參數傳入fasync_helper()函數即可。
在設備資源可以獲得時,應該調用kill_fasync()釋放SIGIO信號。在可讀時,第3個參數設置為POLL_IN,在可寫時,第3個參數設置為POLL_OUT。

⑩ Linux中非同步IO模型有哪些

1)阻塞I/O(blocking I/O)
2)非阻塞I/O (nonblocking I/O)
3) I/O復用(select 和poll) (I/O multiplexing)
4)信號驅動I/O (signal driven I/O (SIGIO))
5)非同步I/O (asynchronous I/O (the POSIX aio_functions))
其中前4種都是同步,最後一種才是非同步。

閱讀全文

與linux的非同步機制相關的資料

熱點內容
windows拷貝到linux 瀏覽:751
mdr軟體解壓和別人不一樣 瀏覽:884
單片機串列通信有什麼好處 瀏覽:320
游戲開發程序員書籍 瀏覽:843
pdf中圖片修改 瀏覽:269
匯編編譯後 瀏覽:474
php和java整合 瀏覽:829
js中執行php代碼 瀏覽:442
國產單片機廠商 瀏覽:57
蘋果手機怎麼設置不更新app軟體 瀏覽:284
轉行當程序員如何 瀏覽:493
蘋果id怎麼驗證app 瀏覽:864
查看手機命令 瀏覽:953
抖音反編譯地址 瀏覽:227
如何加密軟體oppoa5 瀏覽:234
java從入門到精通明日科技 瀏覽:97
拆解汽車解壓視頻 瀏覽:598
新版百度雲解壓縮 瀏覽:593
android上下拉刷新 瀏覽:880
centos可執行文件反編譯 瀏覽:839