1. 程式人生 > >poll實現I/O多路複用

poll實現I/O多路複用

函式原型:


函式說明:該函式允許程序指示核心等待多個事件中的任何一個發生,並只在有一個或多個事件發生的時候才。

喚醒它

引數說明:

fds:是一個struct pollfd 結構體型別的陣列,用於存放需要檢測其狀態的socket描述符。

每當呼叫這個函式之後,系統不會清空這個陣列,特別是對於socket連線比較多的情況下,在一定程度上可以提高處理的效率;這一點與select()函式不同,在呼叫select之後,select()函式會清空它所檢測的socket描述符集合,導致每次呼叫select()函式之後,必須把select描述符重新加入到待檢測的集合中;因此,select()函式適用於select描述符較少且相距較近的情況。

nfds:用於標記fds中的結構體元素的總數量

timeout:poll函式的阻塞時間,單位是毫秒

1、timeout  ==  0,poll立即返回不阻塞

2、timeout  > 0,阻塞的毫秒數

3、timeout == -1,poll一直阻塞,直到所檢測的socket描述符上的感興趣的事件發生才返回。

返回值:

1、 > 0:陣列fds中準備就緒的socket描述符總量

2、== 0:超時

3: -1:出錯

poll與select不同在於描述符儲存方式不同和引數型別不同。

1.結構體陣列的管理:當每次有需要關心的描述符時,將其放入結構體中,每次有無效的描述符後,將其描述符置-1,下次poll函式會忽略它。當有新的描述符加入時,從頭遍歷結構體,將為-1的元素設為要關心的描述符事件狀態。切記:當新的描述符加到結構體陣列末尾時要更新關心描述符個數,即poll第二個引數。

2.每次呼叫poll後,結構體元素revents會儲存就緒事件狀態,當每次重新呼叫poll之前時,系統會自己設定其為0,重新監聽關心事件(不需要使用者重新置0)

3.poll中引數不是輸入,輸出型,因此timeout,struct pollfd *fds引數不需重置,nfds看情況(參照第一點),而select函式是輸入輸出型別,每次呼叫前需重置。

實現IO複用:關心輸入輸出條件就緒:

/*************************************************************************
	> File Name: poll.c
	> Author: fucang_zxx
	> Mail: 
[email protected]
> Created Time: 2016年08月01日 星期一 13時41分06秒 ************************************************************************/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <poll.h> int main(int argc, char* argv[]) { if(argc != 3) { printf("Usage #: %s [ip] [port]\n", argv[0]); exit(1); } //建立陣列,用以指定我們感興趣的檔案描述符上發生的可讀、可寫和異常等事件 //struct pollfd //{ // int fd; /*檔案描述符*/ // short events; /*註冊的事件*/ // short revents; /*實際發生的事件,由核心填充,輸出型*/ //}; struct pollfd fds[2]; fds[0].fd = 0; fds[0].events = POLLIN; /*對讀事件感興趣*/ fds[0].revents = 0; /*輸出型*/ fds[1].fd = 1; fds[1].events = POLLOUT; /*對寫事件感興趣*/ fds[1].revents = 0; char buf[1024]; int done = 0; int i = 0; int timeout = 5000; /*5000毫秒數,即5秒*/ while(!done) { int ret = poll(fds, sizeof(fds)/sizeof(fds[0]), timeout); switch(ret) { case -1: perror("poll"); exit(2); break; case 0: printf("timeout...\n"); break; default: //有事件就緒,但還需判斷是哪個檔案描述符的什麼事件 //int i = 0; for(i = 0 ; i < sizeof(fds)/sizeof(fds[0]); ++i) { //是否可讀 //fds[i]所關心的事件是讀,而且有讀事件發生 if( fds[i].fd == 0 && (fds[i].revents & POLLIN) ) { memset(buf, '\0', sizeof(buf)); ssize_t _s = read(0, buf, sizeof(buf) - 1); if(_s > 0) { buf[_s - 1] = '\0'; if(strncmp(buf, "quit", 4) == 0) { close(fds[i].fd); exit(0); } printf("echo#: %s\n", buf); } } /*注意:標準輸出一直成立*/ else if( fds[i].fd == 1 & (fds[i].revents & POLLOUT) ) { memset(buf, '\0', sizeof(buf)); strcpy(buf,"hello fucang"); printf("echo#: %s\n", buf); } } break; } } return 0; }


相關推薦

poll實現I/O

函式原型: 函式說明:該函式允許程序指示核心等待多個事件中的任何一個發生,並只在有一個或多個事件發生的時候才。 喚醒它 引數說明: fds:是一個struct pollfd 結構體型別的陣列,用於存放需要檢測其狀態的socket描述符。 每當呼叫這個函式之後,系

網路程式設計(4)select函式實現I/O伺服器

    我按理解整了個基於select模式的單程序多路複用併發伺服器,並寫了個簡單的測試程式測了下,雖然離實用還差得遠,但用來練習select夠用了。 至於如何實現的細節,程式碼註釋算比較清楚,就不多弄了。 一。伺服器部份 單程序併發伺服器程式碼: /*********

嵌入式Linux網路程式設計,I/Opoll()示例,poll()客戶端,poll()伺服器,單鏈表

文章目錄 1,IO複用poll()示例 1.1,poll()---net.h 1.2,poll()---client.c 1.3,poll()---sever.c 1.4,poll()---linklist.h 1.5,p

嵌入式Linux網路程式設計,I/O,阻塞I/O模式,非阻塞I/O模式fcntl()/ioctl(),I/O select()/pselect()/poll(),訊號驅動I/O

文章目錄 1,I/O模型 2,阻塞I/O 模式 2.1,讀阻塞(以read函式為例) 2.2,寫阻塞 3,非阻塞模式I/O 3.1,非阻塞模式的實現(fcntl()函式、ioctl() 函式)

I/O之select、poll、epoll

很早之前有寫過篇IO多路複用的文章:https://www.cnblogs.com/klcf0220/archive/2013/05/14/3077003.html 參考連結:https://segmentfault.com/a/1190000003063859 select,poll,epoll都是IO多路

淺談網路I/O模型 select & poll & epoll

我們首先需要知道select,poll,epoll都是IO多路複用的機制。I/O多路複用就通過一種機制,可以監視多個描述符,一旦某個描述符就緒(一般是讀就緒或者寫就緒),能夠通知程式進行相應的讀寫操作。但select,poll,epoll本質上都是同步I/O,因為他們都需要在讀寫事件就緒後自己負責進行讀寫,

I/O——poll

上一篇我們說了關於select的相關資訊,我們可以看到select是有弊端的,所以為了解決select的弊端,UNIX又在後期提出了poll。 select的弊端這裡就不多說了,上一篇部落格有提及。 poll poll和select類似,不過在一些

Linux網路程式設計---I/O之select

1.I/O多路複用(IO multiplexing) 我們之前講了I/O多路複用和其他I/O的區別,在這裡,我們再具體討論下I/O多路複用是怎麼工作? I/O 多路複用技術就是為了解決程序或執行緒阻塞到某個 I/O 系統呼叫而出現的技術,使程序不阻塞於某個特定的 I/O 系統呼叫。

I/O

I/O型別:     接下來我們將介紹幾種常見的I/O模型及其區別         阻塞I/O:blocking I/O(如果沒有資訊,則阻塞)       

【Linux】I/O

五種IO模型     阻塞IO(等待魚上鉤)         在核心將資料準備好之前,系統呼叫會一直等待,所有的套接字,預設是阻塞模式。         等待,拷貝資料到buf中,(等待的時間長)     非阻塞IO(定期檢視是否有魚上鉤)         如果核心還未將資料

I/O技術(multiplexing)

作者:知乎使用者 連結:https://www.zhihu.com/question/28594409/answer/52835876 來源:知乎 著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。 下面舉一個例子,模擬一個tcp伺服器處理30個客戶soc

嵌入式Linux網路程式設計,I/O,epoll()示例,epoll()客戶端,epoll()伺服器,單鏈表

文章目錄 1,I/O多路複用 epoll()示例 1.1,epoll()---net.h 1.2,epoll()---client.c 1.3,epoll()---sever.c 1.4,epoll()---linklist.h

嵌入式Linux網路程式設計,I/O,select()示例,select()客戶端,select()伺服器,單鏈表

文章目錄 1,IO複用select()示例 1.1 select()---net.h 1.2 select()---client.c 1.3 select()---sever.c 1.4 select()---linklist.h

UNIX網路程式設計-I/O

目錄 Unix下可用的5種I/O模型 阻塞式I/O模型 非阻塞式I/O模型 I/O複用模型 訊號驅動式I/O模型 非同步I/O模型 各種I/O模型的比較 參考   Unix下可用的5種I/O模型 阻塞式I/O 非阻塞式I/O

IO基礎入門之I/O技術

在I/O程式設計過程中,當需要同時處理多個客戶端接入請求時,可以利用多執行緒或者I/O多路複用技術進行處理。I/O多路複用技術通過把多個I/O的阻塞複用到同一個select的阻塞上,從而使得系統在單執行緒的情況下可以同時處理多個客戶端請求。與傳統的多執行緒/多程序模型比,I

I/O伺服器程式設計

一、實驗目的 理解I/O多路複用技術的原理。 學會編寫基本的單執行緒併發伺服器程式和客戶程式。 二、實驗平臺 ubuntu-8.04作業系統 三、實驗內容 採用I/O多路複用技術實現單執行緒併發伺服器,完成使用一個執行緒處理併發客戶請求的功能。 四、實驗原理 除了可以採用多

I/O之 epoll 系統呼叫

I/O多路複用除了之前我們提到的select和poll外,epoll 也可以檢查多個檔案描述符的就緒狀態,以達到I/O多路複用的目的。 epoll 系統呼叫是 Linux 系統專有的,在 Linux 核心 2.6 版本新增,epoll 的主要優點有: 當檢

Socket網路程式設計_之I/O

1. IO多路複用: 每一次網路通訊都是一個Socket的I/O流,對於伺服器而言,有兩種方法 1.傳統的多程序併發模型(每進來一個新的I/O流會分配一個新的程序管理。) 2.方法二就是I/O的多路複用

Linux 下I/O總結

 select,poll,epoll都是IO多路複用的機制。I/O多路複用就通過一種機制,可以監視多個描述符,一旦某個描述符就緒(一般是讀就緒或者寫就緒),能夠通知程式進行相應的讀寫操作。但select,poll,epoll本質上都是同步I/O,因為他們都需要在讀寫事件

I/O詳解(三)

    在linux的網路程式設計中,很長的一段時間都在使用select來做事件觸發。然而select逐漸暴露出了一些缺陷,使得linux不得不在新的核心中尋找出替代方案,那就是epoll。其實,epoll與select原理類似,只不過,epoll作出了一些重大改進,即:     a、當它們所監聽的集合中有狀