Select function and I/O multi-Channel transfer __ function

Source: Internet
Author: User
Tags readable

Turn from: http://blog.csdn.net/linyt/article/details/1722445

Select function and I/O multi-Channel transfer


For example, you can write code that reads and writes IO operations, such as reading data from a socket, using the following code:

while ((n = Read (SOCKETFD, buf, bufsize)) >0)

if (Write (Stdout_fileno, buf, n) = N)

{

printf ("Write error");

Exit (1);

}

When the SOCKETFD descriptor in the code corresponds to a file table entry that is blocked, it blocks until data is sent from the other end of the network. If it is a server program that reads and writes a large number of sockets, blocking on one socket will obviously affect the interaction with other sockets. Similar problems occur not only on the web, but also in a series of situations, such as reading and writing locked files and FIFO, and so on.

A better solution seems to be to implement it with non-blocking IO. The socketfd of the data to be read is set to Non-blocking, followed by the Read function to check if there is data coming, if so, it will return to the number of data, or it will return 1 to indicate that no data is currently available. In this way, for each socket, if there is data arrival read, no will return immediately. This is the benefit of non-blocking IO. Some of the code is as follows:

Clientfd[] is the number of socket descriptor groups for the client, assuming that the size of the array is max and that all client socket descriptors are set to non-blocking.

for (i = 0; i < MAX; ++i)

{

int n;

if ((n = read (clientfd[i), buf, Szie)) >0)

{

Send response to the client in.

}

}

The code here doesn't look much different from the code above, but it's a big difference. The difference is that the use of non-blocking io for the entire interaction process, so that each client has a relatively equal time treatment. This pattern is commonly referred to as this "polling" mode. Polling mode also has its drawbacks, in the execution of the read function, in fact, most of the time there is no data readable, but still continue to execute read, wasting a lot of CPU time.


Actually, a better technique for the above problems is I/O multiplexing (I/O multiplexing). It is a trade-off between the above two approaches: first, construct a data table about the descriptor, and then call a function that is only returned if one or more descriptors are ready for IO operations, or blocks. When returned, it tells the process that the descriptor is ready to be IO.

Now the task of implementing a multiple-link assignment falls on the Select function, and now gives you a detailed introduction to the use of the Select function. Our protagonist appeared, hehe. Applause.

Function: Implement multiple-channel transfer by calling the kernel. It provides the following parameters to the kernel

1 The descriptor we care about

2 for each descriptor, we are concerned about the condition (whether to read a given descriptor, or to write a given descriptor, or to care about the exception condition of a descriptor)

3 hope to wait for how long time (can always wait, wait for a fixed time, or completely do not wait)

When returned from Select, the kernel tells us:

1 Number of prepared descriptors

2 which descriptor is ready to read, write, or abnormal conditions

Using this return value, you can invoke the corresponding I/O function, usually read or write, and know that the function will not block.


Definition of function:

#include <sys/types.h>

#include <sys/time.h>

#include <unistd.h>


int select (int maxfdp1, fd_set *readfds, Fd_set *writefds, Fd_set *exceptfds, sturct timeval);

Returns: The prepared descriptor, if the timeout is 0, if the error is-1


The last parameter is a pointer variable of struct TIMEVAL, which specifies the time to wait.

struct timeval{

Long tv_sec; /* Seconds/*

Long tv_usec; /* microsecond Number * *

};


There are three scenarios for parameter tvptr:

If tvptr = NULL is always waiting. If you catch a signal, you interrupt this indefinitely wait. Returns when one or more of the specified descriptors is ready or catches a signal. If a message is captured, the select returns -1,errno set to Eintr.

If tvptr->sec ==0 && tvptr->tv_usec = 0 is not waiting at all. That is, all the descriptors are tested and returned immediately. This is the polling method that gets the state of multiple descriptors without blocking the Select function.

If tvptr->tv_sec!= 00 | | Tvptr->tv_usec!= 0 waits for the specified number of seconds and microseconds. Returns if one of its descriptors is ready, or the specified time value has timed out. If no descriptor is ready when the timeout occurs, the return value is 0. Similar to the first case, this wait may be interrupted by a signal.


The middle three parameters Readfds, Writefds, Exceptfds are pointers to descriptor sets that describe the various descriptors of the readable, writable, and anomalous conditions we care about. This descriptor set exists in a data type called fd_set (defined in the header file select.h). Each descriptor corresponds to a bit of the memory space occupied by the data structure fd_set, and if the I bit is 0, the descriptor representing the value I is not included in the set, and vice versa. For the convenience of the user, the system provides the following four macros to operate.

Fd_zero (Fd_set *fdset); Empty all the bits in the Fdset

Fd_set (int fd, fd_set *fdset); Opening the corresponding bit of FD in Fdset

FD_CLR (int fd, fd_set *fdset); Turn off the bits corresponding to the FD in Fdset

Fd_isset (int fd, fd_set *fdset); Test whether FD is in Fdset


It is usually done by first defining a descriptor set

Fd_set RSet;

int FD;

You must use Fd_zero to clear all its bits

Fd_zero (&rset);

And then set the bit that we care about

Fd_set (FD, &rset);

Fd_set (Stdout_fileno,&rset);

When returning from select, use Fd_isset to test whether one of the sets is still set

if (Fd_isset (FD, &rset)) {

...

}


Any (or all) of these three parameters of the Select function can be null pointers, which means that the corresponding conditions are not concerned. It is worth mentioning that if the three pointers are all empty, the Select function provides a more precise timer than sleep, while the Select function can wait for less than 1 seconds, depending on the system clock.

Select the first parameter maxfdp1 means "maximum FD plus 1 (max FD plus 1)". Find the maximum descriptor value in three descriptor sets, then add 1, which is the first argument. You can also set the first argument to Fd_setsize, which is a constant of <sys/types.h>, usually 256 or 1024. For most applications, however, this value is too large. If you set MAXFDP1 to the maximum descriptor value plus 1, the kernel only needs to look for open bits in this range, instead of searching the top hundreds of for a wide range.

The following is the sample code:

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.