The Select function is still more important in socket programming, but for beginners who are not too fond of using Select to write programs, they are just used to writing such as Connect, accept, Blocking programs such as recv or recvfrom (the so-called block mode block, as the name implies, is that a process or thread must wait for an event to occur when it executes to these functions, and if the event does not occur, the process or thread is blocked and the function cannot be returned immediately). However, a non-blocking (so-called nonblocking mode non-block is done using SELECT, that is, the process or thread does not have to wait for the event to occur, and once the execution is returned, the return value is different to reflect the execution of the function, if the event occurs in the same way as the block. If the event does not occur, return a code to tell the event not to occur, and the process or thread continues to execute, so it is more efficient to work on the program, which can monitor the change of the file descriptor we need to monitor-read-write or exception. Here is a detailed introduction!
The two structures are described first:
1, the Select mechanism provides a data structure struct fd_set, can be understood as a collection, is actually a bitmap, each specific to flag the corresponding size file descriptor, this collection is stored in the file descriptor (descriptor), that is, the file handle ( That is, each bit of the bitmap can be connected with an open file handle (file descriptor), this work is done by the programmer, this can be what we call the ordinary meaning of the file, of course, UNIX under any Device, pipeline, FIFO, etc. are file forms, all included, So there is no doubt that a socket is a file, the socket handle is a file descriptor. The Fd_set collection can be manipulated by a number of macros, and the programmer does the most fd_set operation by manipulating the Class 4 macros:
(1), Fd_zero (Fd_set *) empty a file descriptor set;
(2), fd_set (int, fd_set *) adds a file descriptor to a specified set of file descriptors;
(3), fd_clr (int, fd_set*) removes a given file descriptor from the collection;
(4), fd_isset (int, fd_set*) checks whether the file descriptor specified in the collection can be read or written.
In-depth understanding of the key point of the Select model is to understand fd_set, for the sake of convenience, we 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 as a 0000,0000 in bits.
(2) If FD = 5, after executing fd_set (fd,&set), SET becomes 0001,0000 (5th position 1)
(3) If you add fd=2, fd=1, then 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. When no readable event occurs, FD = 5 is emptied.
2, struct timeval, a commonly used structure, used to represent the time value, there are two members, one is the number of seconds, the other is the number of milliseconds.
[CPP]View PlainCopy
- struct Timeval
- {
- long tv_sec; //second
- long tv_usec; //microsecond
- };
The accuracy of this structure can be as accurate as 1 seconds per million.
Next, we introduce the Select function, which is formatted as:
[CPP]View PlainCopy
- int select (int maxfdp,fd_set *readfds,fd_set *writefds,fd_set *errorfds,struct timeval *timeout);
Explain the parameters of select in detail:
(1) int MAXFDP 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 want 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 above two parameter intent, used to monitor file error exception file.
(5) struct timeval* timeout is the time-out of SELECT, this parameter is important, it can make the 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.
Some reference resolutions for the SELECT function: http://www.groad.net/bbs/read.php?tid-1064.html
The difference between the Select function and the Pselect function reference: http://hi.baidu.com/_jiangming/item/56d5c43fe2cadb4981f1a789
The Pselect function is an enhanced select function that prevents signal interference
Select () Function instance analysis:
Is there data coming on the monitor keyboard under Linux?
[CPP]View PlainCopy
- #include <sys/time.h>
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <assert.h>
- int main ()
- {
- int keyboard;
- int ret,i;
- Char C;
- Fd_set READFD;
- struct Timeval timeout;
- Keyboard = open ("/dev/tty", O_rdonly | O_nonblock);
- ASSERT (KEYBOARD>0);
- While (1)
- {
- Timeout.tv_sec=1;
- timeout.tv_usec=0;
- Fd_zero (&READFD);
- Fd_set (KEYBOARD,&READFD);
- /// monitoring function
- Ret=select (keyboard+1,&readfd,null,null,&timeout);
- if (ret = =-1) //Error condition
- cout<<"Error" <<ENDL;
- Else if (ret) //return value greater than 0 has data coming
- if (Fd_isset (KEYBOARD,&READFD))
- {
- I=read (keyboard,&c,1);
- if (' \ n ' ==c)
- continue;
- printf ("hehethe input is%c\n", c);
- if (' Q ' ==c)
- Break ;
- }
- Else //Timeout condition
- {
- cout<<"Time Out" <<endl;
- continue;
- }
- }
- }
Select function Details (GO)