Libevent Summary (top)

Source: Internet
Author: User

Recently want to write diydb, so want to draw on Libevent event mechanism. I've seen some of Libevent's code before, but it's been clean for a long time. Today take this opportunity to brush up on libevent, write a summary here.

First, Introduction

The biggest aspect of libevent is event-driven and cross-platform, and of course, lightweight. However, its core is definitely an event-driven mechanism. Libevent events are divided into I/O events, timer events, and signal events.


Second, the use of a simple introduction

Here is the application of a timer event for Libevent

1) First initialize the Libevent library and save the returned pointer
struct Event_base * base = Event_init ();
In fact, this step is equivalent to initializing an Reactor instance, and after initializing the libevent, you can register the event. Note: Every Reactor instance in a system that supports Epoll manages a epoll_wait () in the final analysis.


2) Initializing event events, setting callback functions and events of interest
Evtimer_set (&ev, TIMER_CB, NULL);
In fact this is equivalent to calling Event_set (&ev,-1, 0, TIMER_CB, NULL);
The function prototypes for Event_set are:
void Event_set (struct event *ev, int fd, short event, Void (*CB) (int,
short, void *), void *arg)
EV: Executes the event object to initialize;
FD: The "handle" of the event binding, which is the signal of concern for the signal event;
Event: The types of events of interest on the FD, which can be ev_read, Ev_write, ev_signal;
CB: This is a function pointer, when the event on the FD occurs, call the function to perform processing, it has three parameters,
Called by Event_base is responsible for the incoming, in order, in fact, is event_set when the FD, event and Arg;
ARG: The parameter passed to the CB function pointer;
Since the timing event does not require FD, and the timing event is set according to the time-out value of the Add (Event_add),
There is no need to set the event here.
This step is equivalent to initializing an event handler, which is held in libevent in the events structure.
Note: Libevent does not manage the event events collection, which requires the application to manage itself;


3) Set the event dependent Event_base
Event_base_set (base, &ev);
This step is equivalent to specifying which Event_base instance the event is registered to and, in effect, on which epoll the event registry is registered


4) It's time to formally add events.
Event_add (&ev, timeout);
The basic information is set to complete, as long as a simple call to the Event_add () function can be completed, where timeout is a timed value, this step is equivalent to calling

The Reactor::register_handler () function registers the event. This is where the event EV is officially registered with the corresponding event registry


5) The program enters an infinite loop, waits for a ready event and performs event handling
Event_base_dispatch (base);//core is while () {epoll_wait ()};


Iii. Brief introduction of the event processing process


1) First, the application prepares and initializes the event, sets the events type and callback function;

2) Add the event to libevent. For timed events, Libevent uses a small Gan management, key for super
For Signal and I/O events, Libevent puts it into the waiting list (wait lists), which is a
A doubly linked list structure;

3) The program calls the Event_base_dispatch () series function into the infinite loop, waits for the event, taking the Select () function as an example;
Libevent checks the minimum timeout time for a timed event before each cycle of TV, according to the maximum of the TV set Epoll ()
Time, so that the timeout event can be handled in a timely manner;
When Epoll () returns, check the timeout event first, and then check the I/O event;

Libevent all ready events into the activation list;
Event handling is then performed on the callback function that activates the event in the list, invoking the event;


Three, reactor mode

Speaking of Libevent mode, we have to say reactor mode, because Libevent's event-handling mechanism is reactor mode

1. Concept

Reactor the definition of "reactor" is an event-driven mechanism. Register the event and callback function with reactor first, and then when the event occurs, reactor automatically calls the corresponding callback function to handle the event (I/O read-write, timing, and signal). (Note: The pass function is called: The application is not actively calling an API to complete processing)


2. Advantages

Reactor mode is one of the prerequisites for writing high-performance Web servers, and it has the following advantages:
1) The response is fast and does not have to be blocked for a single synchronization time, although the Reactor itself is still synchronous; (the action in the callback function is best non-blocking)
2) programming is relatively simple, can avoid complex multi-threaded and synchronization problems, and avoid multi-threaded/process switching overhead;
3) scalability, can be easily by increasing the number of Reactor instances to make full use of CPU resources;
4) reusability, the reactor framework itself is independent of the specific event handling logic and has high reusability;


3.reactor Frame

Using the Reactor model, several components are required: Event source, Reactor framework, multiplexing mechanism, and event handlers

1) Event Source
Linux is a file descriptor, Windows is a Socket or Handle, here is known as a "handle set", the program on the specified handle register the event of interest, such as I/O events.

2) event demultiplexer--multi-channel distribution mechanism

The I/O multiplexing mechanisms provided by the operating system, such as SELECT and Epoll. The program first registers its concerned handle (the event source) and its events on the event demultiplexer, and when an event arrives, event Demultiplexer notifies "the event of one or more handles is ready in the registered handle set," And when the program receives the notification, The event can be handled in a non-blocking situation. Corresponding to the libevent, is still select, poll, Epoll, etc., but libevent using the structure of eventop encapsulation, with a unified interface to support these I/O multiplexing mechanism, to the external hiding the underlying system mechanism.

3) reactor--reactor
Reactor is an event management interface that internally uses event demultiplexer to register, unregister, and run an event loop that invokes the callback function that registers the event to handle the event when an event enters the ready state. Corresponding to the libevent, is the event_base structure.

4) Event handler--Events Handler
The event handler provides a set of interfaces, each of which corresponds to a type of event that Reactor is invoked when the corresponding event occurs and performs the corresponding event handling. Typically, it binds a valid handle. Corresponds to the libevent, which is the event structure body




Iv. Event Events

Libevent is event-driven (Event-driven), and from the name you can see that the event is the core of the entire library. The event is the Reactor component of the events handler in the framework, which provides a function interface for Reactor to invoke when an event occurs to perform the appropriate event handling, usually binding a valid handle. In fact, events here already include information about the event source and the event handler function


struct Event {tailq_entry (event) ev_next;//A pointer to a doubly linked list node that represents the location of the event in the registered event List of the I/O event tailq_entry (event) ev_active_next;// Represents the position of the event in the registered event list of the activation event, if it is hung, indicating that the event has occurred, waiting for the corresponding event handler to be executed Tailq_entry (event) ev_signal_next;//A pointer to a doubly linked list node, Represents the position of the event in the registered event List of the signal event unsigned int min_heap_idx; If the event is a timeout event, MIN_HEAP_IDX indicates that the event is in the index of the small top heap of the timeout event, struct event_base *ev_base;//ev_base the reactor instance to which the event belongs, which is a event_base struct int ev _FD;//EV_FD, for I/O events, is the binding file descriptor, and for the signal event, is the signal of the binding (actually a well-known pipe descriptor); Short Ev_events;//event the event type of interest short ev_ncalls;// When the event is ready to execute, the number of times the ev_callback is called, typically a 1;short *ev_pncalls;//pointer, usually pointing to Ev_ncalls or null/* allows deletes in callback */struct time Val ev_timeout;//If the event is a timeout event, Ev_timeout represents a time-out event for the supermarket value int ev_pri;/* Smaller numbers is higher priority */void (*ev_callback) (int, short, void *arg);//event's callback function, called by Ev_base, executes the event handler void *ev_arg;int ev_res;//records the type of the current activation event;/* result passed to even T callback */int ev_flags;}; 1) Ev_events:event The event type of interest, it can be the following 3 types: I/O events: Ev_write and Ev_read timing events: Ev_timeout signal: ev_signal auxiliary options: Ev_persist, Indicates that it is a permanent event LiBevent is defined as: #define Ev_timeout 0x01#define ev_read 0x02#define ev_write 0x04#define ev_signal 0x08#define EV_PERSIST 0x1 0/* permanent events, that is, each time an event occurs and is processed, automatically added to the corresponding queue */2) eb_flags:libevent The field used to mark the event information, indicating its current state, the possible values are:
#define EVLIST_TIMEOUT 0x01//event in the time heap
#define EVLIST_INSERTED 0x02//event in the Registered events list
#define Evlist_signal 0x04//not seen in use
#define EVLIST_ACTIVE 0x08//event in the activation list
#define EVLIST_INTERNAL 0x10//Internal use Mark
#define EVLIST_INIT//event has been initialized


The management process of the event is resolved:



Each time an event is turned into a ready state, libevent moves it into the active event List[priority] (priority of the ready events), where priority is the event precedence, and then libevent according to his The scheduling policy selects the Ready event, calls its Cb_callback () function to perform event handling, and populates the parameters of the Cb_callback function with the ready handle and event type.

Before adding an event to Libevent, you must initialize an event, that is, set the event. This is done by invoking the functions provided by libevent: Event_set (), Event_base_set (), Event_priority_set (). Note: Libevent has a global event_base pointer current_base, by default the event EV will be registered to Current_base, which can be used to specify a different event_base; if there are multiple libevent in a process instance, you must call the function to set a different event_base for the event;



Libevent Summary (top)

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.