Libevent Source Depth Analysis

Source: Internet
Author: User
Tags epoll

Original address: http://blog.csdn.net/sparkliang/article/details/4957667

Chapter I.

1, preface

Libevent is a lightweight, open-source, high-performance network library, with many users and researchers, and many related articles. This series of articles is intended to be a sharing of ideas, two of the libevent code and design thinking to do a systematic, deeper analysis, written out, but also for later reference.

The accompanying sentence: Libevent is written in C (Ms Daniel prefers C language), and almost everywhere function pointers, learning its source code also need a considerable C language Foundation.

2,libevent Introduction

Of course the first compliment, Libevent has a few notable highlights:
+ Event Driven (Event-driven), high performance;
+ Lightweight, focus on the network, as ACE is so bloated and huge;
= + Source code is quite refined, easy to read;
+ Cross-platform support for Windows, Linux, *bsd and Mac Os;
+ + supports multiple I/O multiplexing Technologies, Epoll, poll, Dev/poll, select, and Kqueue;
+ = support for I/O, timers and signals and other events;
= = Register event priority;

Libevent has been widely used as the underlying network library, such as memcached, vomit, Nylon, netchat, and so on.

Libevent the current stable version is 1.4.13; This is also the version referenced in this article.

3, the benefits of learning

Learning Libevent can help to improve the programming skills, in addition to network program design, Libevent code has a lot of useful design techniques and basic data structure, such as information hiding, function pointers, C language Polymorphism support, linked list and heap, etc., all help to improve their own program skill.
Programming not only to understand the framework, a lot of detail is precisely the key to the success of the whole system. Just about the framework of libevent itself, that may be just smattering, not in-depth code analysis, it is difficult to understand the design of the delicate place, it is difficult for their own use.

In fact Libevent itself is a typical reactor model, understanding reactor mode is the cornerstone of understanding Libevent, so the next section describes the typical event-driven design pattern--reactor mode.

Reference: libevent:http://monkey.org/~provos/libevent/

Chapter II

As mentioned earlier, the entire libevent itself is a reactor, so this section will be devoted to the reactor model as necessary, and lists several important components of libevnet and reactor correspondence, in later chapters may also refer to the basic concepts described in this section.

the event handling mechanism of 1,reactor

First, recall the mechanism of the normal function call: The program calls a function? function execution, program wait? function returns the result and control to the program? The program continues processing.

Reactor the definition of "reactor" is an event-driven mechanism. Unlike normal function calls, where an application is not actively invoking an API to complete processing, instead of reactor the event processing flow, the application needs to provide the appropriate interface and register it with the reactor, if the corresponding time occurs, Reactor will actively invoke the interfaces registered by the application, which are also known as "callback functions". Using Libevent is also to register the appropriate events and callback functions libevent the framework, and when these times are audible, libevent calls these callback functions to handle the corresponding events (I/O read-write, timing, and signal).

The "Hollywood Principle" to describe reactor is the right one: do not call us, we will call to inform you.

For example: You go to apply for a XX company, after the interview is over.

"Normal function call mechanism" Company HR compared lazy, will not remember your contact way, how to do it, you can only after the interview to call to ask the results, have not been admitted ah, or is the basis;

"Reactor" Company HR wrote down your contact information, the results will be the initiative to call you: Have not been admitted ah, or is the basis; you do not have to call to ask the results, in fact, you do not have the HR stay contact.

2, advantages of reactor mode

Reactor mode is one of the necessary techniques for writing high-performance Web servers, and it has the following advantages

1) Fast response, do not have to be blocked for a single synchronization time, although the reactor itself is still synchronous;
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 mode frame

Using the reactor model, several components are required: Event source, reactor framework, multiplexing mechanism, and event handler, first look at the overall framework of the reactor model, and then describe each component one by one.

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 (event source) and its events on the event demultiplexer;
when an event arrives, the event Demultiplexer notifies "that one or more handles are ready in the registered handle set";
once the program is notified, the event can be processed 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.
a typical reactor declaration method

1 classReactor2 {3  Public:4     intRegister_handler (Event_handler *phandler,int Event);5     intRemove_handler (Event_handler *phandler,int Event);6     voidHandle_events (Timeval *PTV);7     // ...8};

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.
Here are two typical event handler class declarations, each with their pros and cons.

1 classEvent_handler2 {3  Public:4     Virtual voidHandle_read () =0;5     Virtual voidHandle_write () =0;6     Virtual voidHandle_timeout () =0;7     Virtual voidHandle_close () =0;8     VirtualHANDLE get_handle () =0;9     // ...Ten }; One classEvent_handler A { -  Public: -     //events maybe read/write/timeout/close. etc the     Virtual voidHandle_events (intevents) =0; -     VirtualHANDLE get_handle () =0; -     // ... -};

4, Reactor event processing flow

As I said earlier, reactor the event flow "inverse", what does the event control flow look like when you use reactor mode?
You can see the following sequence diagram.

5, Summary

The above mentioned the basic concept of reactor, framework and processing flow, to reactor have a basic clear understanding, then to compare to see libevent will be easier to understand, then formally into the Libevent code world, come on!

Resources:
pattern-oriented software Architecture, Patterns for Concurrent and networked Objects, Volume 2

Chapter III

1, preface

Where do you start learning the source code? I think it's a good idea to start with the basic usage scenarios and the whole process of code, and at least from the personal experience, it's more effective to analyze libevent with this method.

2, Basic application scenario

The basic application scenario is also the basic process of using libevnet, consider one of the simplest scenarios and use livevent to set the timer, the application only needs to perform the following simple steps.

1) First initialize the Libevent library and save the returned pointer

1 struct Base = Event_init ();

In fact, this step is equivalent to initializing an reactor instance, and after initializing the libevent, you can register the event.

2) Initializing event events, setting callback functions and events of interest

1 evtimer_set (&ev, TIMER_CB, NULL);

In fact, this is equivalent to calling

1 event_set (&ev,-10, TIMER_CB, NULL);

The function prototypes for Event_set are:

1 void event_set (structeventintshorteventvoid (*CB) (intshortvoidvoid *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 occurs on the FD, call the function to perform processing, it has three parameters, called by the Event_base is responsible for the incoming, in order, is actually event_set when the FD, event and Arg;
ARG: The parameter passed to the CB function pointer;
Because the timing event does not require FD, and the timing event is set according to the time-out value of the add-in (Event_add), the event here does not need to be set.
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

1 event_base_set (base, &ev);  

This step is equivalent to specifying which Event_base instance the event is registered to;

4) It's time to formally add events.

1 event_add (&ev, timeout);

Basic information has been set to complete, as long as the simple call Event_add () function can be completed, where timeout is a timed value;
This step is equivalent to calling the Reactor::register_handler () function to register the event.

5) The program enters an infinite loop, waits for a ready event and performs event handling

1 event_base_dispatch (base);

3, Instance Code

The program code for the example above is shown below

1 struct Eventev;2 structTimeval TV;3 voidTIME_CB (intFd Short Event,void*argc)4 {5printf"Timer wakeup/n");6Event_add (&ev, &TV);//Reschedule Timer7 }8 intMain ()9 {Ten     structEvent_base *Base=event_init (); OneTv.tv_sec =Ten;//10s period ATv.tv_usec =0; -Evtimer_set (&ev, TIME_CB, NULL); -Event_add (&ev, &TV); theEvent_base_dispatch (Base); -}

4, Event processing flow

When an application registers an event with libevent, how does the libevent internally handle it? This basic flow is given in the diagram below.
1) First the application prepares and initializes the event, sets the events type and callback function, which corresponds to the preceding steps 2 and 3;
2) Add the event to libevent. For timed events, the libevent uses a small Gan management, the key is the timeout period, and for signal and I/O events, Libevent puts it into the waiting list, which is a doubly-linked list structure;
3) The program calls the Event_base_dispatch () series function to enter the infinite loop, wait for the event, take the Select () function as an example; before each loop libevent checks the minimum timeout time for the timed event TV, set the maximum wait time for select () based on TV, In order to facilitate timely processing of time-out events;
When select () 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;

5, summary

This section introduces a simple and practical scenario for libevent, and a whirlwind introduction to the Libevent event-handling process, in which the reader should have a basic impression of libevent. The following is a detailed introduction to Libevent's event management Framework (reactor framework in reactor mode), which will be preceded by a simple classification of source code files.

Libevent Source Depth Analysis

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.