IO多路转接模型----(select的模型,select的优缺点,poll的模型,poll的优缺点)
                                                            生活随笔
收集整理的這篇文章主要介紹了
                                IO多路转接模型----(select的模型,select的优缺点,poll的模型,poll的优缺点)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.                        
                                IO多路轉接模型:select/poll/epoll
對大量描述符進行事件監控(可讀/可寫/異常)
select模型
- nfds: 監控的文件描述符集里最大文件描述符加1,因為此參數會告訴內核檢測前多少個文件描述符的狀態
- readfds: 監控有讀數據到達文件描述符集合,傳入傳出參數
- writefds: 監控寫數據到達文件描述符集合,傳入傳出參數
- exceptfds: 監控異常發生達文件描述符集合,如帶外數據到達異常,傳入傳出參數
- timeout: 定時阻塞監控時間,3種情況
- NULL,永遠等下去
- 設置timeval,等待固定時間
- 設置timeval里時間均為0,檢查描述字后立即返回,輪詢
- void FD_CLR(int fd, fd_set *set); //把文件描述符集合里fd清0 將指定的描述符從集合中移除
- int FD_ISSET(int fd, fd_set *set); //測試文件描述符集合里fd是否置1 判斷指定的描述符是否在集合中
- void FD_SET(int fd, fd_set *set); //把文件描述符集合里fd位置1 將指定的描述符添加到集合中
- void FD_ZERO(fd_set *set); //把文件描述符集合里所有位清0 清空描述符集合
select優缺點
實現
select服務端
/** 這個文件封裝一個select類,向外界提供更加簡單點的select監控接口* 將用戶關心socket描述符添加到監控集合中* 從監控集合中移除不再關心的socket描述符* 從開始監控,并且向用戶返回就緒的socket*/#include<vector> #include<sys/select.h> #include"tcpsocket.hpp"class Select {public:Select(): _max_fd (-1){FD_ZERO(&_rfds);//清空集合} bool Add(TcpSocket &sock){int fd = sock.GetFd();//void FD_SET(int fd,fd_set *set)//向set描述符集合中添加fd描述符FD_SET(fd,&_rfds);_max_fd = _max_fd > fd ? _max_fd : fd; return true;} bool Del(TcpSocket &sock){int fd = sock.GetFd();//void FD_CLR(int fd, fd_set *set)//從set描述符集合中移除FD_CLR(fd,&_rfds);//從最大的往前遍歷for(int i = _max_fd ; i >= 0; i--){//int FD_ISSET(int fd, fd_set *set);//判斷fd描述符是否還在set集合中if(FD_ISSET(i,&_rfds)){_max_fd = i;break;}}} bool Wait(std::vector<TcpSocket>&list,int timeout_sec = 3){struct timeval tv; //超時時間tv.tv_sec = timeout_sec;tv.tv_usec = 0;fd_set set = _rfds;int ret =select(_max_fd + 1, &set, NULL ,NULL,&tv);if(ret < 0){perror("select error");return false;}else if(ret == 0){std::cout<< "select wait timeout\n";return false;}for(int i =0 ;i <= _max_fd; i++){if(FD_ISSET(i,&set)){TcpSocket sock;sock.SetFd(i);list.push_back(sock);}}return true;} private:fd_set _rfds;int _max_fd; };int main() {TcpSocket sock;CHECK_RET(sock.Socket());CHECK_RET(sock.Bind("192.168.145.132",9000));CHECK_RET(sock.Listen());Select s;s.Add(sock); while(1){std::vector<TcpSocket>list;if(s.Wait(list)==false){continue;}for(int i =0 ; i < list.size(); i++){//判讀socket是監聽socket還是通信socketif(list[i].GetFd() == sock.GetFd()){TcpSocket clisock;std::string cli_ip;uint16_t cli_port;if(sock.Accept(clisock,cli_ip,cli_port) == false){continue;}s.Add(clisock);}else{std::string buf;if(list[i].Recv(buf) == false){s.Del(list[i]);list[i].Close();continue;}std::cout<<"client say:"<<buf <"\n";}}}sock.Close();return 0; }客戶端
#include <signal.h> #include "tcpsocket.hpp"void sigcb(int signo){printf("connection closed\n"); } int main(int argc, char *argv[]) {if (argc != 3) {std::cout<<"./tcp_cli 192.168.122.132 9000\n";return -1; } std::string ip = argv[1];uint16_t port = atoi(argv[2]);signal(SIGPIPE, sigcb);TcpSocket sock;CHECK_RET(sock.Socket());CHECK_RET(sock.Connect(ip, port));while(1) {std::string buf;std::cout <<"client say:";fflush(stdout);std::cin >>buf;sock.Send(buf);}sock.Close();return 0; }
 
 
poll模型
poll函數接口
#include <poll.h>int poll(struct pollfd *fds, nfds_t nfds, int timeout);// pollfd結構 struct pollfd { int fd; /* 用戶監控的描述符 */ short events; /* 描述符關心的事件 POLLIN/POLLOUT */ short revents; /* 描述符實際就緒的事件 */ }參數說明
- fds是一個poll函數監聽的結構列表. 每一個元素中, 包含了三部分內容: 文件描述符, 監聽的事件集合, 返回的事件集合. 描述事件結構數組
- nfds表示fds數組的長度. 要監控事件個數
- timeout表示poll函數的超時時間, 單位是毫秒(ms).
events和revents的取值:
實現原理
使用poll監控標準輸入
#include <poll.h> #include <unistd.h> #include <stdio.h>int main() { struct pollfd poll_fd; //一個結構就是一個事件poll_fd.fd = 0; poll_fd.events = POLLIN; //可讀事件for (;;) { //開始監控int ret = poll(&poll_fd, 1, 1000); //遍歷輪詢 if (ret < 0) { //出錯perror("poll"); continue; }if (ret == 0) { //超時printf("poll timeout\n"); continue; } //ret>0if (poll_fd.revents == POLLIN) { //看事件是否為我們所關心的事件 //對事件進行操作 char buf[1024] = {0}; read(0, buf, sizeof(buf) - 1); printf("stdin:%s", buf); } } }poll有缺點分析
優點:
缺點
總結
以上是生活随笔為你收集整理的IO多路转接模型----(select的模型,select的优缺点,poll的模型,poll的优缺点)的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 在部署依赖比较多的包,例如angular
- 下一篇: 输卵管堵塞还能自然通开吗
