Linux I/O multiplexing--epoll

Source: Internet
Author: User

1, Epoll ()

Epoll () is a Linux-specific I/O multiplexing function, and its implementation differs greatly from the use and select (), poll ().

Epoll () uses a set of functions to accomplish a task, not a single function, and secondly, epoll () places the file description in the kernel event table with an additional file descriptor that identifies the unique event table in the kernel.

The API to use:

int epoll_create (int size);

int epoll_ctl (int epfd, int op, int fd, struct epoll_event *event);

Structure information you need to use:

typedef union Epoll_data {void *ptr;  int FD;  In general, this is the file descriptor uint32_t u32; uint64_t U64;}      Epoll_data_t;struct epoll_event {uint32_t events;        /* Epoll Events */epoll_data_t data; /* USER Data variable */};

int epoll_wait (int epfd, struct epoll_event *events, int maxevents, int timeout);

2, Epoll_wait ()

Key: The core understanding of the epoll_wait () function

(1), return value: The number of ready clients in the event table;

(2), parameters events: Put the information of the ready client in the event table into the events array.

3. The core idea of Epoll ()

is to create a kernel event table that holds the sockets and current events of the listening client, using the epoll_wait () function to find a ready socket, and finally adding, deleting, and modifying the use of the Epoll_ctl () function; Of course, there are a number of macros used in conjunction with it;

3. Code implementation

(1), utili.h

#include <unistd.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <sys /socket.h> #include <arpa/inet.h> #include <netinet/in.h> #include <assert.h> #include <sys/ select.h> #define SERVER_IP "127.0.0.1" #define Server_port 8787#define listen_queue 5#define SIZE 10#define buffer_  SIZE 256#include<poll.h> #define OPEN_MAX 1000#include<sys/epoll.h> #define FDSIZE 1000#define EPOLLEVENTS 100

(2), ser.c

#include ". /utili.h "Static int socket_bind (const char *ip, int port) {     int listenfd = socket (af_inet, sock_stream, 0);     struct  sockaddr_in addrSer;    addrSer.sin_family = AF_INET;   &NBSP;&NBSP;//ADDRSER.SIN_ADDR.S_ADDR&NBSP;=&NBSP;INET_ADDR (IP);     inet_pton (AF_INET, &NBSP;IP,&NBSP;&AMP;ADDRSER.SIN_ADDR);     addrser.sin_port = htons (port);     bind (listenfd,  (struct sockaddr*) &addrser, sizeof (STRUCT&NBSP;SOCKADDR)); &NBSP;&NBSP;&NBSP;&NBSP;RETURN&NBSP;LISTENFD;} Static void add_event (int epollfd, int fd, int state) {     struct epoll_event ev;    ev.events = state;     ev.data.fd = fd;    epoll_ctl (Epollfd, epoLl_ctl_add, fd, &ev);} Static void delete_event (int epollfd, int fd, int state) {     struct epoll_event ev;    ev.events = state;     ev.data.fd = fd;    epoll_ctl (epollfd, epoll_ctl_del, fd,  &ev);} Static void modify_event (int epollfd, int fd, int state) {     struct epoll_event ev;    ev.events = state;     ev.data.fd = fd;    epoll_ctl (epollfd, epoll_ctl_mod, fd,  &ev);} Static void handle_accept (INT&NBSP;EPOLLFD,&NBSP;INT&NBSP;LISTENFD) {    int  clifd;    struct sockaddr_in addrcli;    socklen_t  len = sizeof (STRUCT&NBSP;SOCKADDR);     clifD = accept (listenfd,  (struct sockaddr*) &addrcli, &len);     if (clifd != -1) {        add_event (EPOLLFD,&NBSP;CLIFD,  epollin);     }}static void do_read (int epollfd,  int  FD,&NBSP;CHAR&NBSP;*BUF) {    int nread = read (fd, buf, BUFFER_ SIZE);     if (nread == -1) {        close ( FD);         delete_event (Epollfd, fd, epollin);     }else{        printf ("read msg:>%s\n", buf);         modify_event (epollfd, fd, epollout);     }}static void do_write (INT&NBSP;EPOLLFD,&NBSP;INT&NBSP;FD,&NBSP;CHAR&NBSP;*BUF) {     int nwritE = write (Fd, buf, strlen (BUF) +1);     if (nwrite == -1) {         close (FD);         Delete_event (epollfd, fd, epollout);    } else{         modify_event (Epollfd, fd , epollin);    }     memset (buf, 0, buffer_size);} Static void handle_events (Int epollfd, struct epoll_event *events, int  num,                             int listenfd, char *buf ) {    int i;    int fd;    for (i=0;  i<num; ++i) {        fd = eventS[i].data.fd;        if (FD==LISTENFD)  &&  (Events[i] . Events&epollin)  //into three states according to their results              handle_accept (EPOLLFD,&NBSP;LISTENFD);   //application and Server connection          else if (Events[i].events & epollin)              do_read (EPOLLFD,&NBSP;FD,&NBSP;BUF);   //read-only          else if (events[i].events & epollout)                      do_write (EPOLLFD,&NBSP;FD, &NBSP;BUF);   //write     }}static void do_epoll (INT&NBSP;LISTENFD) {     int ret;    char buffer[BUFFER_SIZE];     Struct epoll_event events[epollevents];    int epollfd = epoll_create (FDSIZE);     add_event (Epollfd, listenfd, epollin);     for (;;) {        //select poll         ret = epoll_wait (epollfd, events, epollevents, -1);         handle_events (Epollfd, events, ret, listenfd, buffer);     }    close (EPOLLFD);} Int main (void) {    int listenfd;    listenfd =  Socket_bind (Server_ip, server_port);     listen (Listenfd, listen_queue);     do_epoll (LISTENFD);     return 0;}

(3), CLI.C

#include ". /utili.h "Static void add_event (int epollfd, int fd, int state) {     struct epoll_event ev;    ev.events = state;     ev.data.fd = fd;    epoll_ctl (EPOLLFD,&NBSP;EPOLL_CTL_ADD,&NBSP;FD,  &ev);} Static void delete_event (int epollfd, int fd, int state) {     struct epoll_event ev;    ev.events = state;     ev.data.fd = fd;     epoll_ctl (EPOLLFD,&NBSP;EPOLL_CTL_DEL,&NBSP;FD,  &ev);} Static void modify_event (int epollfd, int fd, int state) {     struct epoll_event ev;     ev.events = state;     ev.data.fd = fd;     epoll_ctl (EPOLLFD,  epoll_ctl_mod, fd, &ev);} Static void do_read (int epollfd,  int fd, int sockfd, char * BUF) {    int nread = read (fd, buf, buffer_size);     if (nread == -1)  {        close (FD);         delete_event (Epollfd, fd, epollin);     }else{        if (Fd == stdin_fileno)              add_event (Epollfd, fd, epollin);         else{             delete_event (Epollfd, fd, epollin);             add_event (epollfd, stdout_fileno, epollout);        }    }    printf ("Ser :>%s",  buf) ;} Static void do_write (INT&NBSP;EPOLLFD,&NBSP;INT&NBSP;FD,&NBSP;INT&NBSP;SOCKFD,&NBSP;CHAR&NBSP;*BUF) {     int nwrite = write (Fd, buf, strlen (BUF) +1);     if (nwrite == -1) {        perror ("write");         close (FD);    }else{         if (Fd == stdout_fileno) {             delete_event (epollfd, fd, epollout);         }else{            modify_event (EPOLLFD,  fd, epollin);        }    }       &nBsp; memset (buf, 0, buffer_size);} Static void handle_events (Int epollfd, struct epoll_event *events, int  num,                 &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;INT&NBSP;SOCKFD,&NBSP;CHAR&NBSP;*BUF) {     int i;    int fd;    for (i=0; i <num; ++i) {        fd = events[i].data.fd;         if (Events[i].events & epollin)              do_read (EPOLLFD,&NBSP;FD,&NBSP;SOCKFD,&NBSP;BUF);         else if (EVENTS[I].EVENTS,&NBSP;FD,&NBSP;SOCKFD,&NBSP;BUF)              do_write (EPOLLFD,&NBSP;FD,  sockfd, buf);     }}static void handle_connection (INT&NBSP;SOCKFD) {     struct epoll_event events[EPOLLEVENTS];    int  Epollfd = epoll_create (fdsize);     add_event (epollfd, stdin_fileno,  Epollin);    int ret;    char buffer[buffer_size];     for (;;) {        ret = epoll_wait (epollfd, events,  EPOLLEVENTS,&NBSP;-1);         handle_events (Epollfd, events,  ret, sockfd, buffer);     }    close (EPOLLFD);} Int main (void) {    int sockfd = socket (Af_inet, sock_stream, &NBSP;0);     struct sockaddr_in addrser;    addrser.sin_ Family = af_inet;     addrser.sin_port = htons (server_port);     addrser.sin_ ADDR.S_ADDR&NBSP;=&NBSP;INET_ADDR (SERVER_IP);     connect (sockfd,  (struct  sockaddr*) &addrser, sizeof (struct sockaddr));     handle_connection (SOCKFD);     close (SOCKFD);     return 0;}

Run results

Server-side is waiting for the use of the client;

Client 1

650) this.width=650; "Src=" Http://s3.51cto.com/wyfs02/M01/88/17/wKioL1fpqXei35d_AAAZ3YfRI20994.png-wh_500x0-wm_3 -wmp_4-s_1441849682.png "title=" Qq20160927070409.png "alt=" Wkiol1fpqxei35d_aaaz3yfri20994.png-wh_50 "/>

Client 2

650) this.width=650; "Src=" Http://s3.51cto.com/wyfs02/M02/88/17/wKioL1fpqbCTD-LIAAAW7mAZK28187.png-wh_500x0-wm_3 -wmp_4-s_1055467077.png "title=" Qq20160927070510.png "alt=" Wkiol1fpqbctd-liaaaw7mazk28187.png-wh_50 "/>

Using the Epoll () function, the efficiency is more efficient without polling each socket;


This article is from the "11586096" blog, please be sure to keep this source http://11596096.blog.51cto.com/11586096/1856827

Linux I/O multiplexing--epoll

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.