[Nginx] Select, poll, and epoll for I/O multiplexing

Source: Internet
Author: User

You can use the following code to read data from a socket:

While (n = read (socketfd, Buf, bufsize)> 0)

If (write (stdout_fileno, Buf, n) = N)

{

Printf ("write error ");

Exit (1 );

}

When the file table item corresponding to the socketfd descriptor in the Code is blocked, it will be blocked until data is sent from the other end of the network. If it is a server program that needs to read and write a large number of sockets, blocking on a socket will obviously affect the interaction process with other sockets. Similar problems may not only occur on the network, but also a series of situations such as reading, writing, and locking files and FIFO.

A better solution seems to be to use non-blocking Io. Set the socketfd of the data to be read to a non-blocking state, and use the READ function to check whether data has arrived. If yes, it will return the number of data received, otherwise, it returns-1, indicating that no data has arrived. In this way, for each socket, if data arrives, it will be read and no data will be returned immediately. This is the benefit of non-blocking Io. Some code is as follows:

// Clientfd [] indicates the number of socket descriptor groups of the client. Assume that the array size is Max and all socket descriptors of the client are set to non-blocking.

For (I = 0; I <Max; ++ I)

{

Int N;

If (n = read (clientfd [I], Buf, szie)> 0)

{

// Send response to client in here.

}

}

The code here does not seem to be much different from the above Code. In fact, there is a big difference. The difference is that non-blocking Io is used for the entire interaction process, this gives each client a relatively equal time. This mode is usually called the "Round Robin" mode. The Round-Robin mode also has its shortcomings. When the READ function is executed, data is not readable for most of the time, but the READ function is still executed continuously, which wastes a lot of CPU time.

Actually, a better technique for the above problems is I/O multiplexing ). It can be said that the preceding two methods are compatible: first construct a data table related to the descriptor, and then call a function, it is returned only when one or more descriptors are prepared for I/O operations. Otherwise, it is blocked. When returned, it will tell the process that the descriptors are ready for Io.

Select Function

# Include <sys/select. h>

Int select (INT maxfdp1, fd_set * readfds, fd_set * writefds, fd_set * limit TFDs, struct timeval * tvptr );

// Returns the number of ready descriptors. If it times out, 0 is returned. If an error occurs,-1 is returned.

? How do I know which descriptors are ready?

The descriptor number starts from 0. maxfdp1 is the number of descriptors to be checked (starting from 0). readfds, writefds, and limit TFDs are pointers to the descriptor set, each descriptor set is stored in an fd_set data type, which maintains one bit for each possible descriptor. Tvptr specifies the time to wait:

Struct timeval {

Long TV _sec; // seconds

Long TV _uses; // microseconds

};

Poll Function

# Include <poll. h>

Int poll (struct pollfd fdarray [], nfds_t NFDs, int timeout); // returns the number of ready descriptors. If a time-out occurs, 0 is returned. If an error occurs,-1 is returned.

Each array element of the pollfd structure array specifies a descriptor number and the state of interest to it.

Struct pollfd {

Int FD;

Short events;

Short revents;

};

The efficiency is basically the same as that of epoll.

Disadvantages of the epoll model:

 

1. maximum number of concurrent threads, because the FD opened by a process (file descriptor) is limited, which is set by fd_setsize. The default value is 1024/2048, therefore, the maximum concurrency of the select model is limited accordingly. Modify fd_setsize by yourself? Although the idea is good, let's take a look at the following...

 

2. efficiency problems: each select call will linearly scan all FD sets, which will result in a linear decline in efficiency. The consequence of increasing the fd_setsize is that everyone is coming slowly. What? All timeout ??!!

 

3. How does the kernel notify the user of the FD message when copying the kernel/user space memory? On this issue, select adopts the memory copy method.

 

Refer:

Http://blog.csdn.net/linyt/article/details/1722445

Http://blog.csdn.net/sparkliang/article/details/4770655

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.