IO multiplex _ select function, io multiplex _ select function
Select function:
#include <sys/select.h>#include <time.h>#include <sys/types.h>#include <unistd.h>int select(int nfds, fd_set*readfds, fd_set*writefds, fd_set*exceptfds, struct timeval*timeout);
Parameter description:
- Nfds: an integer variable, which is 1 larger than the maximum value of a file descriptor in all file descriptor sets. When using select, you must calculate the maximum value of the file descriptor and pass the value through nfds.
- Readfds: This file descriptor set monitors whether any file in the file set is readable. When select () returns, readfds clears unreadable file descriptors, only readable file descriptors can be read by recv (), read (), and so on.
- Writefds: This file descriptor set monitors whether any file in the file set has data to write. When select () returns, readfds clears unwritable file descriptors, only writable file descriptors are left, which can be read by sending (), write (), and so on.
- Exceptfds: This file set monitors whether any file in the file has an error. In fact, it can also be used to monitor out-of-band data OOB. Out-of-band data is sent to the socket using the MSG_OOB flag. When select () is returned, readfds clears other file descriptors, leaving only readable OOB data.
- Timeout: set the maximum wait time when the event in the file set monitored by select () does not occur. When the wait time is exceeded, the function returns. When the return time-out is NULL, it indicates a blocking operation and will wait until a file descriptor in a monitored file set meets the return conditions. When the value of timeout is 0, select () will return immediately.
- Sigmask: Signal
Return Value:
When a positive value greater than 0 is returned: The file descriptor in the monitored file set meets the preceding requirements.
When it is equal to 0: timeout.
If the value is-1, an error occurs.
Struct timeval structure:
Struct timeval {time_t TV _sec; // Second long TV _usec; // microsecond, that is, 1/1000000 s}
In addition, there are four macro operation file descriptors:
FD_ZERO (): clears the file descriptor set;
FD_SET (): adds a file descriptor to a file descriptor set;
FD_CLR (): obtains a file descriptor from a file descriptor set;
FD_ISSET (): Tests whether a file descriptor is a member of a collection.
Note: There is a maximum limit on the set of file descriptors. The maximum value is FD_SETSIZE. When the maximum value is exceeded, unexpected events may occur. At the same time, you can modify this value, but the efficiency of the monitoring set will be reduced, because the select () round-robin linear, more cool functions, please refer to epoll: epoll has no limit on the maximum number of concurrent connections. The maximum number is the maximum number of files that can be opened. This number is generally greater than 2048. Generally, this number has a great relationship with the system memory. The biggest advantage is that it only manages your "active" connections, but it has nothing to do with the total number of connections. Therefore, in the actual network environment, epoll is much more efficient than select and poll. In the memory copy, epoll uses "Shared Memory" at this point, and this memory copy also omits ---- epoll related functions are written during the day, and now sleeps.
Additional:Example of IO reuse cycle Server Model written using select ()
1 # include <sys/types. h> 2 # include <sys/socket. h> 3 # include <netinet/in. h> 4 # include <time. h> 5 # include <string. h> 6 # include <stdio. h> 7 # include <pthread. h> 8 # include <sys/select. h> 9 # define BUFFLEN 1024 10 # define SERVER_PORT 8888 11 # define BACKLOG 5 12 # define CLIENTNUM 1024/* Maximum number of supported clients */13 14/* file descriptors that can be connected to the client array */15 int connect_host [CLIENTNUM]; 16 int connect_number = 0; 17 18 // process the client request Function 19 static void * handle_request (void * argv) 20 {21 time_t now;/* time */22 char buff [BUFFLEN]; /* send and receive data buffer */23 int n = 0; 24 25 int maxfd =-1;/* maximum listen file descriptor */26 fd_set scanfd; /* Collection of listen descriptors */27 struct timeval timeout;/* timeout */28 timeout. TV _sec = 1;/* timeout after 1 second blocking */29 timeout. TV _usec = 0; 30 31 int I = 0; 32 int err =-1; 33 (;;) 34 {35/* maximum file descriptor value initialized to-1 */36 maxfd =-1; 37 FD_ZERO (& scanfd);/* clearing file descriptor Set * /38 for (I = 0; I <CLIENTNUM; I ++)/* put the file descriptor into the Set */39 {40 if (connect_host [I]! =-1)/* Valid file descriptor */41 {42 FD_SET (connect_host [I], & scanfd ); /* put in the Set */43 if (maxfd <connect_host [I])/* update the maximum file descriptor value */44 {45 maxfd = connect_host [I]; 46} 47} 48} 49/* select wait */50 err = select (maxfd + 1, & scanfd, NULL, NULL, & timeout); 51 switch (err) 52 {53 case 0:/* timeout */54 break; 55 case-1:/* error occurred */56 break; 57 default: /* has a readable socket file descriptor */58 if (connect_number <= 0) 59 break; 60 for (I = 0; I <CLIENTNUM; I ++) 61 {62/* search for the active file descriptor */63 if (connect_host [I]! =-1) 64 if (FD_ISSET (connect_host [I], & scanfd) 65 {66 memset (buff, 0, BUFFLEN ); /* reset */67 n = recv (connect_host [I], buff, BUFFLEN, 0);/* receive sender data */68 if (n> 0 &&! Strncmp (buff, "TIME", 4)/* determine whether data is legally received */69 {70 memset (buff, 0, BUFFLEN ); /* reset */71 now = time (NULL);/* current time */72 sprintf (buff, "% 24s \ r \ n", ctime (& now )); /* copy the time to the buffer */73 send (connect_host [I], buff, strlen (buff), 0 ); /* send data */74} 75/* update the value of the file descriptor in the array */76 connect_host [I] =-1; 77 connect_number --; /* client counter minus 1 */78/* close client */79 close (connect_host [I]); 80} 81} 82 break; 83} 84} 85 86 return NULL; 87} 88 89 // processing client connection function 90 static void * handle_connect (void * argv) 91 {92 int s_s = * (int *) argv ); /* Get the server listening socket file descriptor */93 int s_c =-1;/* connect to the client file descriptor */94 struct sockaddr_in from; 95 int len = sizeof (from ); 96/* receive client connection */97 for (;) 98 {99 int I = 0; 100 int s_c = accept (s_s, (struct sockaddr *) & from, & len);/* receive client requests */101 printf ("a client connect, from: % s \ n", inet_ntoa (from. sin_addr); 102/* find the appropriate location, put the file descriptor of the client into */103 for (I = 0; I <CLIENTNUM; I ++) 104 {105 if (connect_host [I] =-1)/* Find */106 {107/* And put */108 connect_host [I] = s_c; 109 110/* client counter plus 1 */111 connect_number ++; 112/* continue polling waiting for client connection */113 break; 114} 115} 116 return NULL; 118} 119 120 int main (int argc, char * argv []) 121 {122 int s_s;/* server socket file descriptor */123 struct sockaddr_in local; /* local address */124 int I = 0; 125 memset (connect_host,-1, CLIENTNUM); 126 127 128/* establish TCP socket */s_s = socket (AF_INET, SOCK_STREAM, 0); 129 130/* initialize the address. */131 memset (& local, 0, sizeof (local);/* reset */132 local. sin_family = AF_INET;/* AF_INET protocol family */133 local. sin_addr.s_addr = htonl (INADDR_ANY);/* any local address */134 local. sin_port = htons (SERVER_PORT);/* server port */135 136/* bind the socket file descriptor to the local address and port */137 int err = bind (s_s, (struct sockaddr *) & local, sizeof (local); 138 err = listen (s_s, BACKLOG);/* listen */139 140 pthread_t thread_do [2]; /* thread ID */141/* Create thread to process client connections */142 pthread_create (& thread_do [0],/* thread ID */143 NULL, /* attribute */144 handle_connect,/* thread callback function */145 (void *) & s_s ); /* thread parameter */146/* Create thread to process client requests */147 pthread_create (& thread_do [1],/* thread ID */148 NULL, /* attribute */149 handle_request,/* thread callback function */150 NULL);/* thread parameter */151/* Waiting for thread end */152 for (I = 0; I <2; I ++) 153 pthread_join (thread_do [I], NULL); 154 155 close (s_s); 156 157 return 0; 158}
Author: orange1438 Source: Shanghai.