Thoroughly learn how to use the epoll (C): Examples of ET read Analysis

Editor: wind over the summer ChinaUnix blog

First look at a program, this program want to achieve function when the user has any input from the console operation, the output "hello world!".

l a program

  1. #include <unistd.h>
  2. #include <iostream>
  3. #include <sys/epoll.h>
  4. using namespace std;
  5. int main(void)
  6. {
  7.     int epfd,nfds;
  8.     struct epoll_event ev, events [5]; // ev registered for the event, an array of events for the return to be processed
  9.     epfd = epoll_create (1); // need only listen to one descriptor - standard input
  10.     ev.data.fd=STDIN_FILENO;
  11.     ev.events = EPOLLIN | EPOLLET; // read status while listening mode settings ET
  12.     epoll_ctl (epfd, EPOLL_CTL_ADD, STDIN_FILENO, & ev); // register epoll event
  13.     for(;;)
  14.    {
  15.      nfds=epoll_wait(epfd,events,5,-1);
  16.      for(int i=0;i<nfds;i++)
  17.      {
  18.         if(events[i].data.fd==STDIN_FILENO)
  19.            cout<<"hello world!"<<endl;
  20.      }
  21.    }
  22. }

operation result:

A program to monitor the use of ET in standard input mode, the results we want to achieve the function. So how is it practical principle, we will analyze the process:

(1) When a user enters a set of characters, which is fed into the buffer set of characters, the characters remain in the buffer, the buffer and because of empty to not empty, so return to read ET Ready, output "hello world!".

After (2) epoll_wait program execution again, although this time the contents of the buffer readable, but according to our analysis in the previous section, ET is not ready to return, resulting in epoll_wait obstruction. (Underlying cause of ET is ready fd of epitem only be placed rdlist once).

(3) the user to enter again a group of characters, resulting in an increase in the content of buffer in accordance with our analysis in the previous section, this will lead to a change fd state, is the corresponding epitem join rdlist again, so that epoll_wait return ready for reading, output again "hello world! ".

 We look at how the situation LT, the program will be one of the following modifications:

    ev.events = EPOLLIN; // default mode LT

operation result:

 

Results As expected, the program dead cycle, since any user input data, the data is sent and no buffer is read out, so that the LT mode, each buffer that are readable epoll_wait returned ready for reading. Cause every time output "hello world!". Look at the following two procedures.

l Procedure 2

  1. #include <unistd.h>
  2. #include <iostream>
  3. #include <sys/epoll.h>
  4. using namespace std;
  5. int main(void)
  6. {
  7.     int epfd,nfds;
  8.     char buf[256];
  9.     struct epoll_event ev, events [5]; // ev registered for the event, an array of events for the return to be processed
  10.     epfd = epoll_create (1); // need only listen to one descriptor - standard input
  11.     ev.data.fd=STDIN_FILENO;
  12.     ev.events = EPOLLIN; // Use default mode LT
  13.     epoll_ctl (epfd, EPOLL_CTL_ADD, STDIN_FILENO, & ev); // register epoll event
  14.     for(;;)
  15.    {
  16.      nfds=epoll_wait(epfd,events,5,-1);
  17.      for(int i=0;i<nfds;i++)
  18.      {
  19.        if(events[i].data.fd==STDIN_FILENO)
  20.        {
  21.           read (STDIN_FILENO, buf, sizeof (buf)); // the contents of the buffer are read out
  22.           cout<<"hello world!"<<endl;
  23.        }
  24.     }
  25.   }
  26. }

 

operation result:

Procedure 2 still use the LT model, but each time epoll_wait return when we are ready to read the contents of the buffer (buffer) read out, resulting buffer empty again, the next call epoll_wait will be blocked. So we can achieve the desired function - when the user input from the console of any operation, the output "hello world!". We look at the procedures III.

l Procedure 3

 

  1. int main(void)
  2. {
  3.     int epfd,nfds;
  4.     struct epoll_event ev, events [5]; // ev registered for the event, an array of events for the return to be processed
  5.     epfd = epoll_create (1); // need only listen to one descriptor - standard input
  6.     ev.data.fd=STDIN_FILENO;
  7.     ev.events = EPOLLIN | EPOLLET; // use the default mode LT
  8.     epoll_ctl (epfd, EPOLL_CTL_ADD, STDIN_FILENO, & ev); // register epoll event
  9.     for(;;)
  10.    {
  11.      nfds=epoll_wait(epfd,events,5,-1);
  12.      for(int i=0;i<nfds;i++)
  13.      {
  14.        if(events[i].data.fd==STDIN_FILENO)
  15.         {
  16.           cout<<"hello world!"<<endl;
  17.           ev.data.fd=STDIN_FILENO;
  18.           ev.events = EPOLLIN | EPOLLET; // use the default mode LT
  19.           epoll_ctl (epfd, EPOLL_CTL_MOD, STDIN_FILENO, & ev); // re-MOD event (ADD invalid)
  20.         }
  21.      }
  22.    }
  23. }

 

 

Procedure 3 still use ET, but after each reading readiness are active MOD IN event again, we find that the program infinite loop again, that is, each time you return ready for reading. This is verified on an ET to discuss the third case ready for reading. Note, however, if we change the MOD ADD, will not have any effect. Do not forget to ADD a description of each character will be in the red-black tree consisting of epitem add an item, before we once had ADD, ADD will stop again added, so call to ADD IN event will not have any effect.

Guess you like

Origin www.cnblogs.com/abelchao/p/11703780.html