Original address: Http://www.cnblogs.com/ccsccs/articles/4224253.html "invasion and deletion"
In Linux, we can use the Select function to reuse the I/O port, and the parameters passed to the Select function tell the kernel:
? The file descriptor that we care about
? For each descriptor, we are concerned about the state. (whether we want to read or write from a file descriptor, or if there is an exception in a descriptor)
? How long do we have to wait? (We can wait for an infinite amount of time, to wait for a fixed period of time, or not to wait at all)
After returning from the Select function, the kernel tells us the message:
? The number of descriptors that have been prepared for our requirements
? For three conditions which descriptor is ready. (read, write, abnormal)
With these return information, we can call the appropriate I/O functions (usually read or write), and these functions will no longer block.
|
#include <sys/select.h> int Select (int maxfdp1, fd_set *readset, Fd_set *writeset, fd_set *exceptset,struct timeval *timeout); |
Returns: the number of file descriptors prepared, time-out is 0, error is-1.
First, let's take a look at the last parameter. It indicates the time we have to wait:
struct timeval{
long tv_sec; /* sec */
long tv_usec; /* microseconds */
}
There are three types of cases:
Timeout = NULL waits for an infinite length of time. The wait can be interrupted by a signal. The function returns when there is a descriptor ready or when a signal is captured. If a signal is captured, the Select function returns-1, and the variable Erro is set to Eintr.
Timeout->tv_sec = = 0 &&timeout->tv_usec = = 0 do not wait, return directly. The descriptor that joins the descriptor set is tested and returns the number of descriptors that satisfy the requirement. This method obtains multiple file descriptor states without blocking by polling.
Timeout->tv_sec!=0 | | timeout->tv_usec!= 0 waits for the specified time. The function returns when there is a descriptor that meets the criteria or exceeds the time-out. Returns 0 if the time-out is about to run out but the condition is not described. In the first case, the wait is also interrupted by the signal.
The middle of the three parameters Readset, Writset, Exceptset, points to the descriptor set. These parameters indicate which descriptors we care about, and what conditions (writable, readable, abnormal) we need to meet. A file description set is saved in the Fd_set type. The Fd_set type variable represents a descriptor for each bit. We can also think of it as just an array of many bits. As shown in the following:
For variables of type fd_set All we can do is declare a variable, assign a value of the same type variable to the variable, or use the following macros to control it:
|
#include <sys/select.h> int Fd_zero (int fd, fd_set *fdset); int FD_CLR (int fd, fd_set *fdset); int Fd_set (int fd, fd_set *fd_set); int Fd_isset (int fd, fd_set *fdset);</span> |
The Fd_zero macro sets all bits of a fd_set type variable to 0, using fd_set to place a position on the variable. You can use FD_CLR when you clear a bit, and we can use Fd_set to test whether a bit is set.
When a set of file descriptors is declared, all locations must be zeroed with Fd_zero. The position of the descriptor to which we are interested is then manipulated as follows:
|
Fd_set RSet; int fd; Fd_zero (&rset); Fd_set (FD, &rset); Fd_set (stdin, &rset);</span> |
After the select is returned, use the Fd_isset test to set the position:
|
if (Fd_isset (FD, &rset) { ... } </span> |
Explain the parameters of select in detail:
(1) INTMAXFDP is an integer value that refers to the range of all file descriptors in the collection, that is, the maximum value of all file descriptors plus 1, and cannot be wrong.
Description: The explanation of this principle can be seen in a detailed explanation of the above fd_set, Fd_set is to store these file descriptors in the form of bitmaps. MAXFDP defines the number of bits that are valid in the bitmap.
(2) Fd_set*readfds is a pointer to the FD_SET structure, this set should include the file descriptor, we are to monitor the read changes of these file descriptors, that is, we are concerned about whether the data can be read from these files, if there is a file in this collection is readable, Select returns a value greater than 0 indicating that the file is readable, and if there is no readable file, the timeout parameter is used to determine whether to time out, and if timeout is exceeded, select returns 0 if an error returns a negative value. You can pass in a null value to indicate that you do not care about any file read changes.
(3) Fd_set*writefds is a pointer to the FD_SET structure, this set should include the file descriptor, we are to monitor the write changes of these file descriptors, that is, we are concerned about whether the data can be written to these files, if there is a file in this collection can be written, Select returns a value greater than 0, indicating that a file is writable, and if there is no writable file, the timeout parameter is used to determine whether to time out, and if timeout is exceeded, select returns 0 if an error returns a negative value. You can pass in a null value to indicate that you do not care about any file write changes.
(4) Fd_set*errorfds with the intent of the above two parameters, used to monitor file error exception file.
(5) structtimeval* timeout is the time-out of SELECT, this parameter is critical, it can make select in three states, first, if NULL is passed as a parameter, that is, the time structure is not passed in, that is, the select is put in a blocking state, Be sure to wait until one of the file descriptors in the monitor file descriptor collection changes; second, if the time value is set to 0 seconds 0 milliseconds, it becomes a purely non-blocking function, regardless of whether the file descriptor is changed, immediately return to continue execution, the file has no change return 0, there is a change to return a positive value; Timeout value is greater than 0, this is the waiting time-out period, that is, select in timeout time block, the timeout period has the arrival of the event to return, otherwise after the timeout, anyway must return, the return value with the above.
Description
function returns:
(1) The Kernel (I/O) modifies the set of file descriptors based on the state and returns a number greater than 0 when the corresponding file descriptor set of the monitor satisfies the criteria, such as when the data arrives in the set of read file descriptors.
(2) The Select function returns a value of 0 when there is no file descriptor that satisfies the condition, and the set Timeval monitoring time times out.
(3) An error occurs when Select returns a negative value.
Understanding Select Model:
The key to understanding the Select model is to understand fd_set, for illustrative convenience, take fd_set length of 1 bytes, each bit in fd_set can correspond to a file descriptor FD. The 1-byte-long fd_set can correspond to 8 fd maximum.
(1) Execute fd_set set; Fd_zero (&set); The set is represented by a bit 0000,0000.
(2) If fd=5, execute Fd_set (fd,&set), then SET to 0001,0000 (5th position 1)
(3) If you add fd=2,fd=1 again, set becomes 0001,0011
(4) Execute select (6,&set,0,0,0) blocking wait
(5) If a readable event occurs on the fd=1,fd=2, select returns, at which point the set becomes 0000,0011. Note: No event occurs when the fd=5 is emptied.
Based on the above discussion, it is easy to derive the features of the Select model:
(1) The number of file descriptors that can be monitored depends on the value of sizeof (Fd_set). My side on the server sizeof (fd_set) = 512, each bit represents a file descriptor, then the maximum file descriptor supported on my server is 512*8=4096. It is said to be adjustable, although it can be adjusted, the upper limit is dependent on the value of the variable when compiling the kernel.
(2) When the FD is added to the Select Monitor set, an array of data structures is used to save the FD in the Select monitoring set, and the array is used as the source data and fd_set for Fd_isset judgment after the select return. Second, the select return will be previously joined but no event of the FD emptied, then each start select before starting to re-get FD from the array to join (Fd_zero first), scan the array at the same time to obtain the FD maximum MAXFD, for the first parameter of select.
(3) The Select model must loop array (plus FD, fetch MAXFD) in front of SELECT, and select Returns a loop array (Fd_isset determines if there is time).
Basic principle
Select () system Call Code for the daytime
The call order is as follows:sys_select () à core_sys_select () à do_select () à fop->poll ()
Resources:
http://blog.csdn.net/tianmohust/article/details/6595998
Http://www.cnblogs.com/jinmu190/archive/2010/11/21/1883184.html
A detailed description of the Linux select function