SELECT () system call and file descriptor set FD

xiaoxiao2021-03-06  38

SELECT () System Call and File Description FD_SET Application Hunan Hengyang Environmental Engineering Company Network Center Zhang Qing is in a network program, and a process simultaneously handles multiple file descriptors. SELECT () system call allows the process to detect multiple I / O devices waiting for the simultaneous I / O device. When there is no device ready, select () blocks, where either device is ready, select () returns. SELECT () call form is: #include #include int search (int maxfd, fd_set * readfds, fd_set * writefds, fe_set * Exceptfds, const struct timeval * timeout) The first parameter of SELECT is the number of bits to be detected in the file descriptor. This value must be at least the maximum file descriptor of the detected; the parameter readfds specifies the read monitoring file descriptor set; parameter writefds designated The file descriptor set for written monitored; and the parameter ExcePTFDS specifies the file descriptor set that is monitored by the exception. The parameter Timeout acts a timer: to the specified time, whether or not there is a device ready, all returns a call. The structure of TimeVal is defined as follows: struct timeval {long TV_sec; // Indicates a few seconds long TV_usec; ​​// means a few subtle} Timeout takes different values, which shows different properties: 1. TIMEOUT is 0, the call is returned immediately; Timeout is null, select () calls to block until you know that there is a file descriptor; 3. Timeout is a positive integer, which is a general timer. When the Select call returns, in addition to those already ready descriptors, SELECT will clear all unsuccessful descriptors in ReadFDs, WriteFDS, and ExceptFDs. The return value of SELECT has the following cases: 1. Number of file descriptors returned under normal conditions; 2. After the time of timeout, there is still no equipment for a long time, the return value is 0; 3. If SELECT is interrupted by a signal, it will return -1 and set errno to Eintr. 4. If an error, return -1 and set the corresponding Errno. The system provides four macros for operation: #include #include void fd_set (int FD, fd_set * fdset); void fd_clr (int FD, fd_set * fdset); Void fd_isset (int FD, fd_set * fdset); Void fd_zero (fd_set * fdset); Macro FD_SET Settings File Descriptor Set Fdset Position corresponding to the file descriptor FD (set to 1), macro FD_CLR Clear file description The bit set fdset corresponds to the bit (set to 0) of the file descriptor FD, macro FD_ZERO Clears all bits in the FDSET (set all bits to 0). Using these three macros When set the descriptor mask bit before calling Select, use the fd_isset after calling SELECT to detect whether the file descriptor set fdset corresponds to whether the file descriptor FD is set. In the past, the descriptor set was achieved as an integer bit shield code, but this implementation would not work for more than 32 file descriptors. Descriptors are now typically represented by bit fields in an integer array, each bit of array elements corresponds to a file descriptor.

For example, an integer accounts for 32 bits, then the first element of the integer array represents the file descriptor 0 to 31, the second element of the array represents the file descriptor 32 to 63, and so on. The macro fd_set sets the bit of the integer array corresponding to the FD file descriptor. The macro fd_clr sets the bit of 0 in the integer array corresponding to the FD file descriptor. The macro fd_zero sets all the bits in the integer array. 0. Suppose it is performed after the following procedures: #include #include fd_set readset; fd_zero (& readset); fd_set (5, & readset); fd_set (33, & readset); file descriptor The corresponding bit corresponding to the file descriptor 6 and 33 in the set readset is set to 1, as shown in Figure 1: After executing the following procedure: fd_clr (5, & readset); then the file descriptor set readset corresponds to the file descriptor 6 The corresponding bit is set to 0, as shown in FIG. General, usually, the operating system declares the maximum number of file descriptors operated by SELECT in one process through macro fd_setsize. For example: we can see in the 4.4BSD header file: #ifndef fd_setsize #define fd_setsize 1024 #ENDIF in the red cap Linux header file we can see: #define __fd_setsize 1024 and at the head Document We can see: #include #define fd_setsize __fd_setsize is defined to only fd_setsize is 1024, an integer accounts for 4 bytes, both 32 bits, then use 32 An integer array of an element to represent a file descriptor set. We can modify this value in the header file to change the size of the file descriptor set used by SELECT, but must recompile the kernel to make the modified value valid. The current version of the UNIX operating system does not limit the maximum of FD_SETSIZE, usually only limited by memory and system management. After we understand that the implementation mechanism of the file descriptor set can be used. (The following procedure runs in the Red Hat Linux 6.0, the function fd_isempty is used to determine if the file descriptor set is empty; the function fd_fetch Removes all file descriptors in the file descriptor set) #include #include #include #include strunt my_fd_set {fd_set fs; // Definition file descriptor set FS unsigned int nConnect; // file descriptor set FS Chinese descriptor Number Unsigned int nmaxfd; // file Description The largest file descriptor} in the FS}; / * Function FD_ISEMPTY is used to determine if the file descriptor set is empty, returns to 1, not to return 0 * / INT FD_ISEMPTY (STRUCT MY_FD_SET * PFS) {INT i; / * File Descriptor Set FD_SET is implemented by an integer array, so the number of elements of the integer array MySet is the number of bytes of the file descriptor set FD_SET in the memory space. Use the number of bytes accounted for an integer.

* / unsigned int mySet [sizeof (fd_set) / sizeof (int)); / * Copy file descriptor set PFS-> FS to array myset * / memcpy (MySet, & PFS-> FS, SIZEOF (FD_SET)); for (i = 0; i fs, sizeof (fd_set)); / * Except for maximum file descriptor MAXFD With the number of digits occupied by integers, it is derived that the corresponding element of the corresponding element corresponding to the integer array MySet in the file descriptor concentration is to reduce the number of retries * / nfind = Tempset-> nmaxfd / (Sizeof) INT * 8); for (i = 0; i <= nfind; i ) {/ * If an element of the array MySet is 0, the 32-bit total of the file descriptor set corresponding to this element is 0, then Continue to judge the next element. * / if (MySet [i] == 0) Continue; / * If an array myset is not 0, it will indicate that the 32-bit of the file descriptor set of this element is 1, put mySet [i ] Assigning the value to the temporary variable ntemp, operates NTEMP, converts the bit of 1 into the corresponding file descriptor * / ntemp = mySet [i]; / * Nbit records the number of binary bits of integers, to NTEMP from low to high Perform & 1 operation until the highest bit, or until the number of file descriptors in the file descriptor is equal to 0 * / for (nbit = 0; Tempset-> nConnect && (Nbit

转载请注明原文地址:https://www.9cbs.com/read-75380.html

New Post(0)