C + +-network programming model-Linux Epoll__c language

Source: Internet
Author: User
1. Introduction (from blog.csdn.net/trojanpizza/article/details/6656671)  

Linux I/O multiplexing technology is used in a number of TCP network servers, that is, more use of the Select function. A new way to improve network I/O performance in the Linux 2.6 kernel is epoll. What Epoll is. According to the Man Handbook, the poll is improved for handling large volume handles. To use Epoll, only the following three system function calls are required: epoll_create(2),epoll_ctl(2),epoll_wait(2).


defect of 2.select model

(1) in the Linux kernel, the fd_set used by the Select is limited

The kernel has a parameter __fd_setsize that defines the number of handles per Fd_set: #define __FD_SETSIZE 1024. That is, it is not possible to use Select if you want to detect the readable state of 1025 handles at the same time, or it is impossible to detect the writable state of 1025 handles at the same time.

(2) implementation of select in kernel using polling method

Each detection iterates through the handles in all fd_set, obviously the execution time of the Select function is proportional to the number of handles in the Fd_set, that is, the more handles the select is to detect, the more time-consuming


defect of 3.Windows IOCP model

The AIO that Windows completes the port implementation is actually only implemented using the internal thread pool, and the final result is that IO has a thread pool and your application needs a pool of threads. Many documents have actually pointed to the cost of the thread context-switch that this raises.


advantages of the 4.EPOLL model

(1) Support a process to open a large number of socket descriptors (FD)

Epoll does not have the restriction in the Select model, which supports the maximum number of open files, which is generally much larger than the 2048 supported by the Select

(2) IO efficiency does not decrease linearly with the increase of FD number

Another Achilles heel of traditional select/poll is that when you have a large socket set, because the network has to delay, so that only part of the socket is "active", and select/poll each call will be linear scan all the collection, resulting in a linear decline in efficiency. But Epoll does not have this problem, it only operates on "active" sockets: This is because in the kernel implementation Epoll is implemented according to the callback function above each FD. So, only "active" socket will be active to call the callback function, the other idle state of the socket will not. At this point, Epoll implements a "pseudo" AIO, as the driving force is in the OS kernel. In some benchmark, if all of the sockets are basically active, such as a high-speed LAN environment, Epoll is no less efficient than select/poll, but if the excessive use of the call Epoll_ctl, the efficiency slightly reduced. However, once the idle connections is used to simulate the WAN environment, the epoll efficiency is far above select/poll.

(3) using MMAP to accelerate message delivery between kernel and user space

Whether Select,poll or epoll require the kernel to notify users of the FD message, it is important to avoid unnecessary memory copies. At this point, the Epoll is implemented through the kernel in the user space mmap the same memory.


working mode of 5.EPOLL model

(1) LT mode

Lt:level triggered, which is the default mode of work, supports both block and No-block sockets, in which the kernel tells you if a file descriptor is ready, and then you can io the ready fd. If you don't do anything, the kernel will continue to notify you, so this pattern is less likely to be programmed incorrectly. Traditional Select/poll are representative of this model.

(2) et mode

lt:edge-triggered, this is a high-speed mode of operation, only support no-block socket. In this mode, when the descriptor is never ready to become ready, the kernel tells you through Epoll, and then it assumes you know that the file descriptor is ready, and no more ready notifications are sent for that file descriptor until you do something that causes that file descriptor to be no longer in the ready state (for example, you're sending , receiving or accepting the request, or sending a ewouldblock error when the received data is less than a certain amount. Note, however, that the kernel will not send more notifications (only once) if the FD has not been used as an IO operation (causing it to become not ready again). However, in the TCP protocol, the Acceleration utility of ET mode still needs more benchmark confirmation.


How to use the 6.EPOLL model

all functions used by Epoll are declared in the header file sys/epoll.h , which briefly describes the data structures and functions used:

(1) epoll_data, epoll_data_t, Epoll_event

typedef Union Epoll_data {

void *ptr;

int FD;

__uint32_t u32;

__uint64_t U64;

} epoll_data_t;

struct epoll_event {

__uint32_t Events;

epoll_data_t data;

};

The structure body epoll_event is used to register events of interest and to return events that occur pending. The events field of the epoll_event structure is an event of interest and an event that is triggered, and may be evaluated as:

Epollin: Indicates that the corresponding file descriptor can be read;

epollout: Indicates that the corresponding file descriptor can be written;

Epollpri: Indicates that the corresponding file descriptor has an urgent data readable;

Epollerr: Indicates that the corresponding file descriptor has an error;

epollhup: Indicates that the corresponding file descriptor is hung;

Epollet: Indicates the corresponding file description have event occurs;

Federation Epoll_data is used to hold data related to a file descriptor that triggers an event. For example, a client connected to the server, the server by invoking the Accept function can be obtained by the client corresponding socket file descriptor, you can describe the file assignments to the Epoll_data FD field, so that the subsequent reading and writing operations on this file descriptor.

(2) epoll_create

function declaration : intepoll_create(intsize)

function Description: This function generates a Epoll-specific file descriptor with parameters that specify the maximum scope of the build descriptor.

(3) epoll_ctl function

function declaration : intepoll_ctl(int epfd,int op, int fd, struct epoll_event *event)

function Description: This function is used to control events on a file descriptor, to register events, modify events, and delete events.

EPFD: a epoll-specific file descriptor generated by epoll_create;

op: The operation to be carried out, the possible value of Epoll_ctl_add registration, Epoll_ctl_mod modification, epoll_ctl_del delete;

FD: the associated file descriptor;

event: pointer to epoll_event;

Returns 0 if the call succeeds, or 1 if unsuccessful.

(4) epoll_wait function

function declaration : int epoll_wait (int epfd, structepoll_event * events, int maxevents, int timeout)

function Description: This function is used to poll I/O events.

EPFD: a epoll-specific file descriptor generated by epoll_create;

epoll_event: An array of events for the postback process;

maxevents: The number of events that can be handled each time;

Timeout: timeout value waiting for I/O event to occur;

Returns the number of events that occurred.

Design ideas:

First you create a epoll handle by create_epoll (int Maxfds), where Maxfds is the maximum number of handles supported by your epoll. This function will return a new epoll handle, and all subsequent operations will be manipulated through this handle. When you are finished, use close () to turn off the created Epoll handle.

Then in your network main loop, call epoll_wait (int epfd, epoll_event events, int max_events,int timeout) to query all network interfaces, see which one can read and which one can write. The basic syntax is:

Nfds = epoll_wait (KDPFD, events, maxevents,-1);

Where KDPFD is the handle created with Epoll_create, events is a epoll_event* pointer, and when the epoll_wait function succeeds, all the read and write events will be stored in the event. Max_events is the number of all socket handles that are currently listening. The last timeout parameter indicates the timeout condition of the epoll_wait, which returns at 0, and the function waits until an event returns, or, for any positive integer, if there is no event, and then returns. In General, if the network main loop is single-threaded, you can use-one to wait, which can guarantee some efficiency, if it is with the main loop on the same thread, you can use 0来 to ensure the efficiency of the main cycle . After the epoll_wait returns, you should go into a loop to traverse all the events.

The operation on Epoll is so simple, in total 4 api:epoll_create, epoll_ctl,epoll_wait and close. Here is an example of a man.

struct epoll_event ev, *events;

for (;;)

{

Nfds = epoll_wait (KDPFD, events, maxevents,-1); Waiting for IO events

for (n = 0; n < Nfds; ++n)

{

If the event is a primary socket, a new connection is entered and a new connection needs to be processed.

if (EVENTS[N].DATA.FD = = listener)

{

Client = accept (listener, struct sockaddr *) &local, &addrlen);

if (Client < 0)

{

Perror ("Accept error");

Continue

}

Putting a new connection in non-blocking mode

setnonblocking (client);

ev.events = Epollin | Epollet;

Note the parameters here Epollin | Epollet does not set up the listening for the write socket,

If there is a write operation, this time Epoll will not return the event,

If you want to listen to the write operation, it should be Epollin | Epollout | Epollet.

and joins the new connection to the Epoll listening queue.

EV.DATA.FD = client;

After setting the event, the new event is passed Epoll_ctl

if (Epoll_ctl (KDPFD, Epoll_ctl_add, client, &ev) < 0)

{

Join Epoll's listening queue, with Epoll_ctl_add

To add a new Epoll event. can be reduced by Epoll_ctl_del.

A Epoll event that changes the way an event is monitored by epoll_ctl_mod.

fprintf (stderr, "Epoll set insertion error:fd=%d" 0, client);

return-1;

}

}

Else

This is an event for a user's socket if it is not an event for the primary socket.

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.