multiplexed input/Output----SELECT

Source: Internet
Author: User

First, select

The system provides a select function to implement a multiplexed input/output model. The select system call is used to let our program monitor the state changes of multiple file handles. The program stops at select here to block the wait until one or more of the monitored file handles has changed state.

The file handle is actually an integer, and our most familiar handle is 0, 1, 23, 0: Standard input, 1: Standard output, 2: standard error output. 0, 1, 2 is an integer representation of the corresponding file * structure: stdin, stdout, stderr.

Second, select related

1, select function//Can wait for more than one descriptor at a time

#include <sys/select.h>

int select (int Nfds, fd_set *readfds, Fd_set *writefds,

Fd_set *exceptfds, struct timeval *timeout);

(1) Parameters:

Nfds: The maximum file descriptor value +1 that needs to be monitored;

Readfds: A collection of readable file descriptors that need to be detected;

Wtitefds: A collection of writable file descriptors that need to be detected;

Exceptfds: A collection of exception file descriptors that need to be detected;

Timeout: Structure timeval, used to set the wait time for select ();

Timeout

Null:select () No timeout,select will always be blocked until an event occurs on a file descriptor.

0: Detects only the state of the descriptor collection and then returns immediately without waiting for an external event to occur.

Specific time value: If no event occurs during the specified time period, select will time out to return.

(2) return value:

Successful execution returns the number of changes in the state of the file descriptor.

Returns 0 if the representation has exceeded the timeout time before the state of the descriptive word has changed;

When an error occurs, 1 is returned, and the reason for the error is stored in errno, at which point the value of the parameter Readfds,writefds,exceptfds and timeout becomes unpredictable.

(3) How select "parameter-value" is passed. Also, the Select File descriptor is qualified.

After the select returns, Fd_isset polling is required to get the ready descriptor.

Select needs to retrieve the ready socket by traversing the file descriptor after returning.

2. Other functions

void fd_clr (int FD, fd_set *set);//Clears the bits of the associated FD in the description phrase set

int fd_isset (int FD, fd_set *set);//test describes whether the bits of the associated FD in the set of phrases are true

void Fd_set (int FD, fd_set *set);//Set the bit of the associated FD in the description phrase set

void Fd_zero (Fd_set *set);//Clears all bits of the description phrase set


#include <aio.h>

int Aio_read (struct AIOCB *aiocbp); Link WITH-LRT.

3. Related structure

struct Timeval {long tv_sec;        /* seconds */long tv_usec;         /* microseconds */};andstruct timespec {long tv_sec;        /* seconds */long tv_nsec; /* nanoseconds */};

Third, select model

1, the key to select model is to understand fd_set, for illustrative convenience, take fd_set length of 1 bytes, fd_set each 1 bit 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.

2. Features:

(1) The number of file descriptors that can be monitored depends on the value of sizeof (Fd_set). If sizeof (fd_set) = 512 on the server, each bit represents a file descriptor, the maximum supported file descriptor on the server is 512*8=4096. Although adjustable, the upper bound 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) Visible Select model must loop array (plus FD, fetch MAXFD) in front of SELECT, select returns Loop array

(Fd_isset determines if there is time to occur).


Four, select server instance:

#include  <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/socket.h># include<arpa/inet.h> #include <netinet/in.h> #include <unistd.h> #include <string.h> #include <errno.h> #include <sys/select.h> #define &NBSP;_BACKLOG_&NBSP;5INT&NBSP;FDS[64];VOID&NBSP;USAGE (const  char *proc) {printf ("%s:[ip][port]\n", proc);} Static int startup (Const char *ip,const int port) {Int sock=socket (AF_INET, sock_stream,0);//Create Socket if (sock < 0) {perror ("socket"); exit (1);} struct sockaddr_in local; //filling Local Information local.sin_family=af_inet;local.sin_port=htons (port); Local.sin _ADDR.S_ADDR=INET_ADDR (IP); if (Bind (sock, (struct sockaddr*) &local,sizeof (local))  < 0)  //bind {perror ("bind"); exit (2);} if (Listen (Sock,_backlog_)  < 0)  //Listen {perror ("listen"); exit (3);} return sock; //return Socket}int main (int argc,char *argv[]) {if (argc != 3) {Usage (argv[0]); return 1;} Char *ip=argv[1];int port=atoi (argv[2]); Int listen_sock=startup (Ip,port); struct  sockaddr_in client;  //Create struct sockaddr_in clientsocklen_t len=sizeof (client);// Take its length client.sin_family=af_inet;client.sin_port=htons (port); client.sin_addr.s_addr=inet_addr (IP); int done=0 ; int new_sock=-1;int max_fd; //fd_set _reads;//readable file descriptor fd_set _writes;//writable file descriptor int  i=0;int fds_num=sizeof (FDS)/sizeof (fds[0])  //file descriptor maximum length for (; i<fds_num;++i)  //to fds[] to initialize {fds[i]=-1;} fds[0]=listen_sock;//first fills the listen_sock   fds[]new_sock=fds[0]; //the fds[0] information in New_sockwhile (!done) { Fd_zero (&_reads);  //0 setting for readable descriptors Fd_zero (&_writes);  fd_set (listen_sock,&_reads);  // Set listen_sock -readable struct timeval _timeout={5,0}; //settings   time-out for (i=1;i<fds_num;++i)  //Save fds[] information to  max_fd[]{if (fds[i] > 0) {fd_set (fds[i],&_reads);  FD_set (fds[i],&_writes); if (FDS[I]&NBSP;&GT;&NBSP;MAX_FD) {max_fd=fds[i];}}} Switch (select (max_fd+1,&_reads,&_writes,null,&timeout))  //select blocking wait {case -1:// Errorperror ("select"); break;case 0://timeoutprintf ("select timeout...\n"); Break;default:{i=0;for (; I <fds_num;++i) {//listen socket readyif (fds[i] == listen_sock && fd_ ISSET (fds[i],&_reads)) {new_sock=accept (Listen_sock, (struct sockaddr*) &client,&len); if (new_ sock < 0) {perror ("accept"); continue;} printf ("get a new connet...%d\n", New_sock); for (i=0;i<fds_num;++i) {if (fds[i] == -1) {fds[i] = new_sock;break;}} if (I == fds_num) {close (New_sock);}} Else if (Fds[i] > 0 && fd_isset (fds[i],&_reads)  && FD _isset (fds[i],&writes))  //listen socket{char buf[1024];ssize_t _size=read (Fds[i],buf, sizeof (BUF)-1); if (_size > 0)//read success{buf[_size]= ';p rintf ("client: %s\n", buf);} Else if (_size == 0)//client close{printf ("client close...\n"); Close (Fds[i]); fds[i]=-1 ; break;} Else{perror ("read");} if (Fd_isset (fds[i],&_writes)) {_size=write (Fds[i],buf,strlen (BUF)), if (_size < 0) {perror ("write ");}} else{printf ("Can ' t write back...\n");}} Else{}}}break;}} return 0;}

Summarize:

Each time a select is called, the FD collection needs to be copied from the user state to the kernel state, and each call to select needs to traverse all the FD that is passed in the kernel, causing the cost of the FD to be too large.


This article is from the "Flower Open Shore" blog, please be sure to keep this source http://zxtong.blog.51cto.com/10697148/1784182

multiplexed input/Output----SELECT

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.