multiplexed I/O poll ()

Source: Internet
Author: User

1. Basic knowledge

The poll mechanism is similar to select in that there is no significant difference in nature with Select, that managing multiple descriptors is also polling and processing according to the state of the descriptor, but poll has no limit on the maximum number of file descriptors. The disadvantage of poll and select is that an array containing a large number of file descriptors is copied in between the user state and the kernel's address space, regardless of whether the file descriptor is ready, and its overhead increases linearly as the number of file descriptors increases.

2. Poll function

The function format is as follows:

# include <poll.h>int poll (struct POLLFD * FDS, unsigned int nfds, int timeout);

The POLLFD structure is defined as follows:

struct POLLFD {

int FD; /* File Descriptor */
Short events; /* Events Waiting for */
Short revents; /* Events that have actually occurred */
} ;

Each pollfd struct specifies a monitored file descriptor that can pass multiple structures, indicating that poll () monitors multiple file descriptors. The events field for each struct is the event mask that monitors the file descriptor, which is set by the user. The Revents field is the action result event mask of the file descriptor, which is set by the kernel when the call returns. Any events requested in the events domain may be returned in the revents domain. The legitimate events are as follows:

The Pollin has data to read.

Pollrdnorm have normal data to read.

Pollrdband has priority data to read.

POLLPRI has urgent data to read.

Pollout write data does not cause blocking.

Pollwrnorm writing normal data does not cause blocking.

Pollwrband Write priority data does not cause blocking.

Pollmsgsigpoll messages are available.

Additionally, the following events may be returned in the revents domain:
Poller An error occurred with the specified file descriptor.

Pollhup the specified file descriptor pending event.

Pollnval The specified file descriptor is illegal.

These events do not make sense in the events field, because they are always returned from revents at the appropriate time.

Using poll () and select () are different, you do not need to explicitly request an exception condition report.
Pollin | Pollpri equivalent to the Read event of select (), Pollout | Pollwrband is equivalent to the Write event of select (). Pollin equivalent to Pollrdnorm | Pollrdband, while pollout is equivalent to Pollwrnorm. For example, to monitor whether a file descriptor is readable and writable at the same time, we can set events to Pollin | Pollout. When poll returns, we can examine the flags in revents, which correspond to the events structure of the file descriptor request. If the Pollin event is set, the file descriptor can be read without blocking. If Pollout is set, the file descriptor can be written without causing blocking. These flags are not mutually exclusive: they may be set at the same time, indicating that the read and write operations of the file descriptor return normally without blocking.

The timeout parameter specifies the number of milliseconds to wait, and poll returns regardless of whether I/O is ready. Timeout is specified as a negative value to indicate an infinite timeout, so that poll () hangs until a specified event occurs, and a timeout of 0 indicates that the poll call immediately returns and lists the file descriptor ready for I/O, but does not wait for other events. In this case, poll (), like its name, returns as soon as it is elected.


Return values and error codes
On success, poll () returns the number of file descriptors that are not 0 in the Revents field in the struct, and if no events occur before the timeout, poll () returns 0; when failed, poll () returns-1, and sets errno to one of the following values:
EBADF the file descriptor specified in one or more structs is invalid.

The address that the Efaultfds pointer points to exceeds the address space of the process.

Eintr the requested event before generating a signal that the call can be re-initiated.

The Einvalnfds parameter exceeds the Plimit_nofile value.

Enomem There is not enough memory available to complete the request.

3. Measure procedure

Write an echo server program, where the client sends information to the server, the server receives the output and sends it back to the client, and the client receives the output to the terminal.

The server-side programs are as follows:

#include <stdio.h>#include<stdio.h>#include"debug.h"#include<sys/socket.h>#include<netinet/inch.h>#include<arpa/inet.h>#include<poll.h>intMain () {intLISTENFD = socket (af_inet, Sock_stream,0); if(-1==listenfd) Errsys ("Socket"); structSockaddr_in myaddr = {0}; structSockaddr_in clientaddr = {0}; Myaddr.sin_family=af_inet; Myaddr.sin_port= Htons (8888); Myaddr.sin_addr.s_addr= Inet_addr ("0.0.0.0");//Inaddr_any    intLen =sizeofmyaddr; if(-1= = Bind (LISTENFD, (structsockaddr*) &myaddr, Len)) Errsys ("Bind"); if(-1= = Listen (LISTENFD,Ten)) Errsys ("Listen");#defineBUFSIZE 100#defineMAXNFD 1024structPOLLFD MYFDS[MAXNFD] = {0};//Define a Readiness status query table with size MAXFDmyfds[0].FD =LISTENFD; myfds[0].events =Pollin; intMaxnum =1; intNready; CharBuf[maxnfd][bufsize] = {0};  while(1)    {        if(-1= = (Nready = Poll (Myfds, Maxnum,-1)) )//asks if the descriptor is ready in the listErrsys ("Poll"); inti =0;  for(;i<maxnum; i++)//socket descriptor in the Traverse list        {            if(Myfds[i].revents & Pollin)//First descriptor read request ready            {                    if(MYFDS[I].FD = = LISTENFD)//Monitor Socket descriptor Ready                {                    intSOCKFD = Accept (LISTENFD, (structsockaddr*) &clientaddr, &len);//Get client sockets                    if(-1==sockfd) Errsys ("Accept"); Debug ("Incoming:%s\n", Inet_ntoa (CLIENTADDR.SIN_ADDR)); MYFDS[MAXNUM].FD= SOCKFD;//to read the client data, add the client socket descriptor to the inquiry tableMyfds[maxnum].events = Pollin;//things to ask: Are you ready to read Pollin server read (client send) pollout server write (clinet receive)maxnum++;//number of descriptors to ask                    if(--nready==0)                        Continue; }                Else                {                    intret = Read (MYFDS[I].FD, BUF[MYFDS[I].FD],sizeofbuf[0]); if(0==ret)                    {Close (MYFDS[I].FD); //client off, release socketMYFDS[I].FD =-1; Continue; } myfds[i].events= Pollout;//when the request is complete, the next interpretation is                }            }            Else if(Myfds[i].revents & Pollout)//I-Descriptor write request ready            {                intret = Write (MYFDS[I].FD, BUF[MYFDS[I].FD],sizeofbuf[0]); printf ("ret%d:%d\n", MYFDS[I].FD, ret); Myfds[i].events= Pollin;//set the read request again. }}} } close (LISTENFD);}

multiplexed I/O poll ()

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.