The use and key analysis of Select,poll,epoll under Linux

Source: Internet
Author: User

Long time useless I/O multiplexing, feel almost forgotten, I remember just learned I/O reuse time spent a lot of times, but because that will not love to write blog, resulting in spending a lot of time to understand things, still easy to forget. As the saying goes, times than hand over again, indeed, in the later study, no matter how difficult or important the knowledge, I will try to write down the form of the blog, so that you can use the blog to urge themselves to learn, but also to deepen the understanding of the knowledge of both its beauty, good nonsense not to say.

Basic overview of I/O multiplexing

I/O multiplexing technology is mainly used to listen to multiple sockets at the same time, so that our program greatly improve performance, generally, the following conditions will be used in the I/O multiplexing technology
(1) The program needs to handle multiple sockets simultaneously
(2) client program needs to handle both user input and network connection
(3) TCP server to handle both the listening socket and the connection socket
(4) The server handles both TCP and UDP requests
(5) Server to process multiple ports at the same time

1.select system Call
#include<sys/select.h>intselect(int*readfds*writefds*exceptfds*timeout);

The. NDF parameter specifies the number of listener file descriptors, which are usually set to all file descriptions multibyte 1 for the Select Listener.
The. Readfds,writefds,exceptfds parameter points to a readable, writable, and unusual event, where the application adds the file descriptor of interest to the corresponding collection, and when the select call returns, the kernel modifies them to notify the application which file descriptors are ready , timeout is the timeout, and the select call successfully returns the number of file descriptors ready
We generally use the following macros to access bits in the Fd_set

#include<sys/select.h>FD_ZERO(fd_set *fdset);     //清除fdset的所有位FD_SET(int fd,fd_set *fdset);//设置fdset的fd位FD_CLR(int fd,fd_set *fdset);//清除fdset的位fdint FD_ISSET(int//测试fdset的位是否被设置

File Descriptor Readiness Condition
(1) The socket core receive buffer is greater than or equal to its low water mark So_rcvlowat. At this point we can read the socket without blocking
(2) The other side of the socket communication closes the connection, at which time the read operation of the socket will return 0
(3) A new connection request is on the monitor socket
(4) There are unhandled errors on the socket
(5) Socket core send buffer is greater than its low water level byte So_sndlowat
(6) After the socket uses a non-blocking connect connection for success or failure
(7) There are unhandled errors on the socket
Specific Examples
Refer to the pseudo-code below

#include <stdio.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <assert.h>#include <unistd.h>#include <stdlib.h>#include <errno.h>#include <string.h>#include <sys/types.h>#include <sys/select.h>intMainvoid){if(ARGC <3)    {cout<<"Wrong parameter"<<endl; }Char*ip = argv[1];intPort = atoi (argv[2]);intRET =0;structSockaddr_in address; Bzero (&address,sizeof(adddress));    address.sin_family = af_inet;    Inet_pton (AF_INET,IP,&AMP;ADDRESS.SIN_ADDR); Address.sin_port = htons (port);intLISTENFD = socket (Af_inet,sock_stream,0); ASSERT (ret! =-1); ret = bind (LISTENFD, (structSOCKADDR *) &address,sizeof(address)); ASSERT (ret! =-1); RET = Listen (LISTENFD,5); ASSERT (ret! =-1);structSockaddr_in client_address; socklen_t len =sizeof(client_address);intCONNFD = Accept (LISTENFD, (structSOCKADDR *) &client_address,&len);if(CONNFD <0)    {cout<<"Error"<<endl;    Close (LISTENFD); }Charbuf[1024x768];    Fd_set Readfds; Fd_zero (&readfds); while(1) {bzero (buf,1024x768);        Fd_set (Connfd,&readfds); ret = SELECT (CONNFD +1, &readfds,null,null,null);if(Ret <0)        {cout<<"Error"<<endl; }//Interpreting whether readable events occur        if(Fd_isset (Connfd,&readfds)) {ret = recv (Connfd,buf,sizeof(BUF)-1,0);if(Ret <=0)            { Break; }cout<<buf<<endl;    }} close (LISTENFD); Close (CONNFD);return 0;}

Features of Select
The internal implementation of select calls the poll (the following will write, so the reader can skip here, read poll, and then look back at this), all of which have the same characteristics as the poll, except that the function interface is different, essentially the same
The characteristics of poll are as follows
(1) Copy the user's incoming POLLFD data (the Descriptor collection corresponding to select) to the kernel space, the copy process event complexity is O (N)
(2) query each file descriptor status, if there is no ready file descriptor, then the process will suspend waiting, know that a time-out or the device driver wakes it again, and then it iterates through all the file descriptors, to find out the file descriptor of the event occurred. Its event complexity is O (N) because it iterates through the file descriptor of 2 times
(3) Copy the acquired data to the user space. Time complexity is also O (N)

Use of 2.poll

The prototype of poll is as follows

#include<poll.h>int poll(struct pollfd *fds,nfds_t nfds,int timeout);

Where FDS is a struct array of type POLLFD, its structure is defined as follows

struct pollfd{    int fd;      //要监听文件描述符    short events;//注册的事件    short revents;//实际发生的事件,内核填充}

The types of events that poll can listen to are as follows (only common ones are listed)

Events Description
Pollin Data can be read
Pollout Data can be written
Pollrdhub The TCP connection was closed by the other, or the other party closed the write operation
Pollhub Hangs, such as the write end of the pipe is closed
Pollerr Error

Nfds the number of file descriptors to listen on
Timeout is a time-out event
File descriptor returned by index poll

int ret = poll(fds,MAX_EVENT_NUMBER,-1);//必须遍历所有文件描述符找到其中的就绪事件(也可以根据已知的就绪个数进行简单的优化)for(int0;i<MAX_EVENT_NUMBER,i++){    if(fds[i].revents & POLLIN)    {        int sock = fds[i];    }}

About the characteristics of poll readers can go back to select to see, before it is written, because it is really said that the internal implementation of the Select mechanism is the same, so there is no need to write extra

Use of 3.epoll

Epoll is a Linux-specific I/O multiplexing function that differs from other I/O multiplexing in implementation and use. It uses a set of functions to accomplish the task, followed by epoll the events on the file descriptor that the user cares about in a single kernel event table. Epoll needs to use an additional file descriptor to uniquely identify the event table in the kernel, and the file descriptor uses epoll_create () to create

#include<sys/epoll.h>int epoll_create(int size);

The size parameter tells the kernel event table how big it needs to be, the file descriptor returned by the function, which will be used for the first argument of all the next functions

The following function is used to manipulate the kernel event table

#include<sys/epoll.h>int epoll_ctl(int epfd,int op,int fd,struct epoll_event *event);

FD is the file descriptor to manipulate, the OP parameter specifies the type of operation, the type of operation is as follows

type of Operation Specific Description
Epoll_ctl_add Registering events on the FD in the event table
Epoll_ctl_mod To modify a registration event on an FD
Epoll_ctl_del To delete a registration event on an FD

The epoll_event structure is defined as follows

struct epoll_event{    _uint32_t events    //epoll事件    epoll_data_t        //用户数据}

Where epoll_data_t is a consortium whose definition is as follows

typedefunion epoll_data{    void *ptr;    int fd;    uint32_t u32;    uint64_t u64;}epoll_data_t

epoll_wait () function
The primary interface of the Epoll event invocation is the Epoll_wait function, which waits for an event on a set of file descriptors within a time-out event

#include<sys/epoll.h>int epoll_wait(int epfd,struct epoll_event *events,int maxevents,int timeout);

Returns the number of ready file descriptors when the function succeeds
If Epoll_wait detects a ready event, it assigns all ready events to the second parameter Epoll_event array, which is used only to output the detected ready events. Array parameters that do not want to be poll are used both for incoming user-registered events and for outputting kernel-detected events, which greatly reduces the efficiency of the application index file descriptor
Use of Epoll

int ret = epoll_wait(epollfd,events,MAX_EVENT_NUMBER,-1);//只需遍历ret个文件描述符for(int0;i<ret;i++){int sockfd = events[i].data.fd;}
特别注意epoll对文件描述符有俩中模式LT和ET,ET是epoll的高效模式

Features of Epoll
Epoll in the kernel implementation is based on each FD on the Russian callback function to achieve, only active FD will actively invoke callback, the other FD will not. If all the file descriptors being monitored are basically active then the Epoll and select or poll gaps are not too large, but if the file descriptor being monitored is only a few active, epoll is much more efficient than the two of them

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

The use and key analysis of Select,poll,epoll under Linux

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.