《電子技術應用》
您所在的位置:首頁 > 嵌入式技術 > 其他 > Linux教學—— 3 分鐘快速了解信號驅動式 IO

Linux教學—— 3 分鐘快速了解信號驅動式 IO

2022-08-12
來源:FPGA之家
關鍵詞: Linux 驅動式IO

  以下是正文:

  一、Linux 的 5 種 IO 模型

  二、如何使用信號驅動式 I/O?

  三、內核何時會發(fā)送 "IO 就緒" 信號?

  四、最簡單的示例

  五、擴展知識

  一、Linux 的 5 種 IO 模型

  阻塞式 I/O:

  系統(tǒng)調用可能因為無法立即完成而被操作系統(tǒng)掛起,直到等待的事件發(fā)生為止。

微信圖片_20220812143203.png

  非阻塞式 I/O (O_NONBLOCK):

  系統(tǒng)調用則總是立即返回,而不管事件是否已經發(fā)生。

微信圖片_20220812143228.png

  I/O 復用 (select、poll、epoll):

  通過 I/O 復用函數(shù)向內核注冊一組事件,內核通過 I/O 復用函數(shù)把其中就緒的事件通知給應用程序。

微信圖片_20220812143308.png

  信號驅動式 I/O (SIGIO):

  為一個目標文件描述符指定宿主進程,當文件描述符上有事件發(fā)生時,SIGIO 的信號處理函數(shù)將被觸發(fā),然后便可對目標文件描述符執(zhí)行 I/O 操作。

  微信圖片_20220812143329.png

  異步 I/O (POSIX 的 aio_ 系列函數(shù)):

  異步 I/O 的讀寫操作總是立即返回,而不論 I/O 是否是阻塞的,真正的讀寫操作由內核接管。

  微信圖片_20220812143450.png

  思考一下,什么時候應該選擇何種 I/O 模型?為何要這么選擇?

  下面重點關注信號驅動式 I/O 這一模型,其他模型可查閱文末參考書籍。

  二、如何使用信號驅動式 I/O?

  一般通過如下 6 個步驟來使用信號驅動式 I/O 模型。

  1> 為通知信號安裝處理函數(shù)。

  通過 sigaction() 來完成:

  int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);

  默認情況下,這個通知信號為 SIGIO。

  2> 為文件描述符的設置屬主。

  通過 fcntl() 的 F_SETOWN 操作來完成:

  fcntl(fd, F_SETOWN, pid)

  屬主是當文件描述符上可執(zhí)行 I/O 時,會接收到通知信號的進程或進程組。

  pid 為正整數(shù)時,代表了進程 ID 號。

  pid 為負整數(shù)時,它的絕對值就代表了進程組 ID 號。

  3> 使能非阻塞 I/O。

  通過 fcntl() 的 F_SETFL 操作來完成:

  flags = fcntl(fd, F_GETFL);

  fcntl(fd, F_SETFL, flags | O_NONBLOCK);

  4> 使能信號驅動 I/O。

  通過 fcntl() 的 F_SETFL 操作來完成:

  flags = fcntl(fd, F_GETFL);

  fcntl(fd, F_SETFL, flags | O_ASYNC);

  5> 進程等待 "IO 就緒" 信號的到來。

  當 I/O 操作就緒時,內核會給進程發(fā)送一個信號,然后調用在第 1 步中安裝好的信號處理函數(shù)。

  6> 進程盡可能多地執(zhí)行 I/O 操作。

  循環(huán)執(zhí)行 I/O 系統(tǒng)調用直到失敗為止,此時錯誤碼為 EAGAIN 或 EWOULDBLOCK。

  原因:

  信號驅動 I/O 提供的是邊緣觸發(fā)通知,即只有當 I/O 事件發(fā)生時我們才會收到通知,

  且當文件描述符收到 I/O 事件通知時,并不知道要處理多少 I/O 數(shù)據(jù)。

  三、內核何時會發(fā)送 "IO 就緒" 信號?

  對于不同類型的文件描述符,情況不一樣。

  1> 終端

  對于終端,當有新的輸入時會會產生信號。

  2> 管道和 FIFO

  對于讀端,下列情況會產生信號:

  數(shù)據(jù)寫入到管道中;管道的寫端關閉;

  對于寫端,下列情況會產生信號:

  對管道的讀操作增加了管道中的空余空間大小。管道的讀端關閉;

  3> 套接字

  對于 UDP 套接字,下列情況會產生信號:

  數(shù)據(jù)報到達套接字;套接字上發(fā)生異步錯誤;

  對于 TCP 套接字,信號驅動式 I/O 近乎無用。

  太多情況都會產生信號,而我們又無法得知事件類型,因此這里就不再列舉其產生信號的情況。

  四、最簡單的示例

  信號處理函數(shù):

  static volatile sig_atomic_t gotSigio = 0;

  static void handler(int sig)

  {

  gotSigio = 1;

  }

  主程序:

  int main(int argc, char *argv[])

  {

  int flags, j, cnt;

  struct termios origTermios;

  char ch;

  struct sigaction sa;

  int done;

  /* Establish handler */

  sigemptyset(&sa.sa_mask);

  sa.sa_flags = SA_RESTART;

  sa.sa_handler = handler;

  if (sigaction(SIGIO, &sa, NULL) == -1) {

  perror("sigaction()\n");

  exit(1);

  }

  /* Set owner process */

  if (fcntl(STDIN_FILENO, F_SETOWN, getpid()) == -1) {

  perror("fcntl() / F_SETOWN\n");

  exit(1);

  }

  /* Enable "I/O possible" signaling and make I/O nonblocking */

  flags = fcntl(STDIN_FILENO, F_GETFL);

  if (fcntl(STDIN_FILENO, F_SETFL, flags | O_ASYNC | O_NONBLOCK) == -1) {

  perror("fcntl() / F_SETFL\n");

  exit(1);

  }

  for (done = 0, cnt = 0; !done ; cnt++) {

  sleep(1);

  if (gotSigio) {

  gotSigio = 0;

  /* Read all available input until error (probably EAGAIN)

  or EOF */

  while (read(STDIN_FILENO, &ch, 1) > 0 && !done) {

  printf("cnt=%d; read %c\n", cnt, ch);

  done = ch == '#';

  }

  }

  }

  exit(0);

  }

  運行效果:

  ./build/sigio

  a

  cnt=0; read a

  cnt=0; read

  abc

  cnt=4; read a

  cnt=4; read b

  cnt=4; read c

  cnt=4; read

  #

  cnt=7; read #

  該程序會先使能信號驅動 IO,然后循環(huán)執(zhí)行計數(shù)操作。

  當有 IO 就緒信號到來時,會去終端讀取數(shù)據(jù)并打印出來,然后繼續(xù)執(zhí)行計數(shù)操作。

  五、擴展知識

  I/O 多路復用 、信號驅動 I/O 以及 epoll 機制可用于監(jiān)視多個文件描述符。

  它們并不實際執(zhí)行 I/O 操作,當某個文件描述符處于就緒態(tài),仍需采用傳統(tǒng)的 I/O 系統(tǒng)調用來完成 I/O 操作。

  相比 I/O 多路復用,當監(jiān)視大量的文件描述符時信號驅動 I/O 有著顯著的性能優(yōu)勢,原因是內核能夠幫進程記錄了正在監(jiān)視的文件描述符列表。

  信號驅動 I/O 的缺點:

  信號的處理流程較為復雜;

  無法指定需要監(jiān)控的事件類型。

  Linux 特有的 epoll 是一個更好的選擇。

  六、相關參考

  UNIX 網絡編程卷1

  6.2 I/O模型25 信號驅動式I/O

  Linux-UNIX 系統(tǒng)編程手冊

  63 其他備選的I/O模型

  Linux 高性能服務器編程

  8.3 I/O 模型

  Linux 多線程服務端編程_使用muduo C++網絡庫

  7.4.1 muduo的IO模型

  更多信息可以來這里獲取==>>電子技術應用-AET<<

微信圖片_20210517164139.jpg

本站內容除特別聲明的原創(chuàng)文章之外,轉載內容只為傳遞更多信息,并不代表本網站贊同其觀點。轉載的所有的文章、圖片、音/視頻文件等資料的版權歸版權所有權人所有。本站采用的非本站原創(chuàng)文章及圖片等內容無法一一聯(lián)系確認版權者。如涉及作品內容、版權和其它問題,請及時通過電子郵件或電話通知我們,以便迅速采取適當措施,避免給雙方造成不必要的經濟損失。聯(lián)系電話:010-82306118;郵箱:aet@chinaaet.com。
亚洲一区二区欧美_亚洲丝袜一区_99re亚洲国产精品_日韩亚洲一区二区
欧美成人精品| 欧美亚州韩日在线看免费版国语版| 亚洲精品欧美激情| 欧美一区二区精美| 亚洲欧美日韩精品久久亚洲区| 夜夜爽www精品| 亚洲免费观看高清完整版在线观看| 亚洲国产日韩一区二区| 亚洲高清不卡一区| 在线日韩中文| 在线观看91久久久久久| 狠狠色狠狠色综合日日tαg| 国产色产综合产在线视频| 国产精品一级久久久| 国产精品区二区三区日本 | 久久久精品国产一区二区三区| 欧美一区免费视频| 久久国产夜色精品鲁鲁99| 久久狠狠一本精品综合网| 久久成人18免费网站| 久久精品女人天堂| 久久影音先锋| 欧美国产视频日韩| 欧美日韩免费在线| 欧美丝袜一区二区| 国产精品视频久久一区| 国产伦精品一区二区三区高清版| 国产欧美日韩另类一区| 国产亚洲人成a一在线v站 | 亚洲激情成人| 日韩亚洲视频在线| 亚洲一区二区成人在线观看| 亚洲欧美在线高清| 久久精品视频va| 亚洲人体大胆视频| 一区二区三区av| 亚欧成人在线| 久久亚洲精品网站| 欧美另类极品videosbest最新版本 | 国产免费成人av| 国精品一区二区三区| 亚洲国产欧美国产综合一区 | 亚洲无毛电影| 欧美在线观看视频在线| 亚洲日本中文字幕免费在线不卡| 一本色道久久综合狠狠躁篇的优点| 亚洲中字在线| 久久免费视频在线观看| 欧美国产亚洲另类动漫| 国产精品久久久久久亚洲毛片| 国产资源精品在线观看| 亚洲人精品午夜在线观看| 亚洲视频在线免费观看| 久久激情视频久久| 亚洲天堂久久| 久久夜色精品国产欧美乱极品| 欧美人与禽猛交乱配| 国产亚洲精品aa| 亚洲免费观看高清在线观看 | 亚洲东热激情| 亚洲视频在线观看网站| 亚洲第一精品久久忘忧草社区| 一区二区三区毛片| 久久手机免费观看| 欧美丝袜一区二区三区| 国自产拍偷拍福利精品免费一| 99riav久久精品riav| 欧美在线地址| 亚洲欧美日本视频在线观看| 老**午夜毛片一区二区三区| 国产精品黄色| 亚洲精品乱码久久久久久日本蜜臀 | 久久网站热最新地址| 欧美日韩系列| 精品91久久久久| 亚洲伊人久久综合| 一本色道久久加勒比精品 | 美女国产一区| 国产欧美二区| 日韩一级黄色av| 亚洲韩国精品一区| 久久国产精品99国产精| 欧美日韩日本网| 亚洲国产精品一区二区www在线| 午夜国产精品视频免费体验区| av成人免费| 欧美jjzz| 国语自产在线不卡| 午夜精品久久久久影视| 亚洲香蕉在线观看| 欧美极品一区| 亚洲高清一二三区| 亚洲高清av| 久久精选视频| 国产精品日韩精品| 99精品欧美一区二区蜜桃免费| 亚洲区免费影片| 久久久久久久久久久一区| 欧美亚洲第一区| 欧美日韩无遮挡| 亚洲成人原创| 午夜亚洲激情| 亚洲欧美视频在线观看| 可以看av的网站久久看| 国产日本亚洲高清| 99re热这里只有精品免费视频| 亚洲国产精品一区二区久| 久久久久成人精品| 国产精品一二| 亚洲主播在线观看| 午夜精品www| 国产精品第三页| 一区二区三区视频观看| 一区二区三区久久网| 欧美国产三级| 亚洲黄色影院| 99精品国产在热久久下载| 欧美国产视频一区二区| 亚洲国产精品久久| 亚洲人成网站在线观看播放| 久热精品视频在线观看| 国产在线播放一区二区三区| 欧美在现视频| 久久天天躁狠狠躁夜夜爽蜜月| 国产日韩欧美夫妻视频在线观看| 亚洲欧美激情视频| 久久大逼视频| 国产一区白浆| 亚洲国产成人精品久久久国产成人一区| 久久久九九九九| 伊人久久大香线蕉av超碰演员| 亚洲国产精品一区二区www| 麻豆久久久9性大片| 亚洲二区三区四区| 亚洲精品一区在线观看| 欧美激情一区二区在线 | 久久精选视频| 在线观看日韩欧美| 亚洲毛片网站| 欧美三级韩国三级日本三斤| 9l国产精品久久久久麻豆| 亚洲综合日韩在线| 国产毛片精品国产一区二区三区| 欧美一级免费视频| 免费观看成人网| 日韩亚洲视频| 午夜在线一区| 国产中文一区二区| 日韩视频不卡| 国产精品国产成人国产三级| 亚洲欧美日韩国产综合| 久久中文久久字幕| 亚洲理论在线观看| 午夜精品久久一牛影视| 韩日在线一区| 夜夜嗨av一区二区三区网站四季av | 亚洲精品乱码久久久久久黑人| 国产精品免费网站| 亚洲色诱最新| 欧美一区视频在线| 伊人久久噜噜噜躁狠狠躁| 日韩一区二区电影网| 欧美日韩亚洲一区二区| 亚洲欧美久久久久一区二区三区| 久久精品国产一区二区电影| 欧美性大战xxxxx久久久| 亚洲免费影院| 久久综合999| 日韩天堂在线观看| 欧美亚洲日本网站| 亚洲电影免费观看高清| 亚洲视频精品| 国产一区二区久久久| av成人福利| 国产日本欧美在线观看| 亚洲精品久久久久久下一站| 欧美三级视频在线播放| 久久av在线看| 欧美日韩午夜在线视频| 欧美一区综合| 欧美日韩一区三区四区| 欧美在线网址| 欧美日韩精品免费观看视频完整| 小黄鸭视频精品导航| 99在线热播精品免费99热| 亚洲国产日韩欧美综合久久| 欧美国产精品v| 亚洲综合日韩| 免费人成精品欧美精品| 在线视频欧美精品| 久久视频在线免费观看| 99在线热播精品免费99热| 久久久久看片| 99国产精品私拍| 久久视频一区| 亚洲色诱最新| 欧美激情成人在线| 香蕉久久精品日日躁夜夜躁| 欧美日韩午夜精品| 亚洲国内精品|