select, poll and epoll models

The last article introduced 5 IO models for Unix network programming. This article introduces the widely used select, poll and epoll models in IO multiplexing. The main idea of ​​IO multiplexing is that it is no longer The application monitors client connections by itself, instead the kernel monitors files for the application

select

/* @Param:
   nfds: 		监控的文件描述符集里最大文件描述符加1,因为此参数会告诉内核检测前多少个文件描述符的状态
   readfds:	监控读数据文件描述符集合,传入传出参数
   writefds:	监控写数据文件描述符集合,传入传出参数
   exceptfds:	监控异常发生文件描述符集合,如带外数据到达异常,传入传出参数
   timeout:	定时阻塞监控时间,3种情况: 
                   1. NULL(永远等下去); 
                   2. 设置timeval,等待固定时间; 
                   3. 设置timeval里时间均为0,检查描述字后立即返回,轮询
 */
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
  1. There is not much difference between using the select model to process IO requests and the synchronous blocking model. There are even more additional operations to add monitoring sockets and call the select function, which is less efficient, but the select model can process multiple socket IO at the same time in one thread Request, that is, if the number of connections processed is not very high, the web server using select is not necessarily better than the web server using multi-threading + blocking IO, and the delay may be greater. The advantage of select is not for a single connection. To process faster, but to be able to handle more connections
  2. Every time you call select, you need to copy the fd_set collection from user mode to kernel mode. If the fd_set collection is large, the overhead is also very high.
  3. Select uses a polling model. Every time you call select, you need to traverse all the fd_sets passed in in the kernel. If the fd_set collection is large, the overhead is also high.
  4. In order to reduce the performance damage caused by data copying and polling fd_set, the kernel limits the size of the monitored fd_set set. This is controlled by the macro FD_SETSIZE. Generally, it is 1024 for 32-bit platforms and 2048 for 64-bit platforms. It simply changes the process. The number of open file descriptors does not change the number of select monitoring files

poll

/*  @Param
	struct pollfd {
		int fd;           /* 文件描述符 */
		short events;     /* 监控的事件 */
		short revents;    /* 监控事件中满足条件返回的事件 */
	};

*/

int poll(struct pollfd *fds, nfds_t nfds, int timeout);
  1. Poll is essentially the same as select, but it has no limit on the maximum number of connections. The reason is that it is stored based on a linked list. It copies the file descriptors passed by the user to the kernel space and then queries the corresponding fd If the device is ready, add an item to the device waiting queue and continue to traverse. If no ready device is found after traversing all fd, the current process will be suspended until the device is ready or actively timeout, and it will have to be awakened Traverse fd again
  2. Polling only solves the limit of the number of file descriptors that select monitors, and does not change the performance overhead caused by copying file descriptors from program space (user space) to kernel space and polling all file descriptors at the bottom of the kernel for each call.

epoll

/* 创建一个epoll句柄,参数size用来告诉内核监听的文件描述符的个数,跟内存大小有关 */
int epoll_create(int size);

/* 控制某个epoll监控的文件描述符上的事件:注册、修改、删除 */
/*  @Param
    epfd:	epoll_creat的句柄
    op:	表示动作,用3个宏来表示:
			EPOLL_CTL_ADD (注册新的fd到epfd),
			EPOLL_CTL_MOD (修改已经注册的fd的监听事件),
			EPOLL_CTL_DEL (从epfd删除一个fd);
    event:	告诉内核需要监听的事件
            struct epoll_event {
			    __uint32_t events; // Epoll events 
			    epoll_data_t data; // User data variable 
		    };
			typedef union epoll_data {
				void *ptr;
				int fd;
				uint32_t u32;
				uint64_t u64;
			} epoll_data_t;
*/
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

/* 等待所监控文件描述符上有事件的产生 */
/*  @Param
    epfd:	    epoll_creat的句柄
    events:	用来存内核得到事件的集合
	maxevents:	告之内核这个events有多大,这个maxevents的值不能大于创建epoll_create()时的size
	timeout:	是超时时间
			    -1:	阻塞
			     0:	立即返回,非阻塞
			    >0:	指定毫秒
    返回值:	    成功返回有多少文件描述符就绪,时间到时返回0,出错返回-1
*/
int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout)
  1. Epoll is an enhanced version of IO multiplexing select/poll under Linux. It can significantly improve the system CPU utilization in the case of a large number of concurrent connections and only a small number of active programs, because it reuses file descriptor sets to deliver results Instead of forcing developers to prepare the set of file descriptors to be listened to each time before waiting for an event, another reason is that when acquiring events, it does not need to traverse the entire set of listened descriptors, as long as it traverses those that are being listened to by the kernel. The IO event wakes up asynchronously and joins the descriptor set of the Ready queue (using a callback mechanism, not a polling method, and the efficiency will not decrease as the number of FDs increases. Only active and available FDs will call the callback function)
  2. Although epoll looks very good on the surface, the performance of select and poll may be better than epoll when the number of connections is small and the connections are very active, because epoll is based on a large number of function callbacks.
  3. In addition to providing level triggers for select/poll IO events (Level Triggered, as long as there is data), epoll also provides edge triggers (Edge Triggered, which is triggered only when data arrives, regardless of whether the buffer is still There is data), which makes it possible for user space programs to cache the IO state, reduce the call of epoll_wait/epoll_pwait, and improve application efficiency

Reference article:
[1]. Why are Redis, Nginx and Netty so fragrant?
[2]. IO-Synchronous, Asynchronous, Blocking, Non-blocking (Remedy)
[3]. Unix Network Programming Synchronous/Asynchronous/Blocking/Non-blocking
[4]. UNIX Network Programming-Socket Synchronous/Asynchronous Blocking/ Non-blocking

If there is any infringement, please contact to delete it. If there is an error, please correct me, thank you

Guess you like

Origin blog.csdn.net/xiao_ma_nong_last/article/details/105236406