In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/01 Report--
This article is a detailed introduction to "how to use Linux high-performance I/O framework library Libevent". The content is detailed, the steps are clear, and the details are properly handled. I hope this article "how to use Linux high-performance I/O framework library Libevent" can help you solve your doubts. Let's go deeper and learn new knowledge together with the ideas of Xiaobian.
There are three types of events that Linux server programs must handle:
I/O event
signal
timed event
When dealing with these three types of events, we usually need to consider the following three questions:
Unify event sources. Obviously, handling all three types of events in a unified way will make the code easy to understand and avoid some potential logic errors.
portability. Different operating systems have different I/O reuse methods, such as dev/poll files in Solaris, kqueue mechanism in FresBSD, and epoll system calls in Linux.
For concurrent programming support, in multi-process and multithreaded environments, we need to consider how the execution entities work together to handle client connections, signals, and timers to avoid race conditions.
Fortunately, the open source community offers a number of excellent I/O frameworks that not only solve these problems, allowing developers to focus entirely on the logic of their programs, but also have excellent stability, performance, and so on. Libevent is a relatively lightweight framework library.
I/O Framework Library Overview
The I/O framework library encapsulates the lower-level system calls in the form of library functions, providing a set of more user-friendly interfaces for applications. These library functions tend to be more reasonable, efficient, and robust than functions of the same functionality implemented by programmers themselves. Because they have withstood the high voltage test in real network environment and the test of time.
The various I/O framework libraries are implemented in a similar way, either in Reactor mode, Procator mode (High Performance Server Program Framework-two efficient event handling modes), or both. For example, the Reactor pattern-based I/O framework library contains several components:
Handle
Event demultiplexer
Event handler
ConcreteEventHandler
Reactor
Handles: Objects that I/O framework libraries handle, i.e. I/O events, signals, and timed events, collectively referred to as event sources. An event source is usually bound to a handle. The purpose of the handle is that when the kernel detects a ready event, it notifies the application of the event through the handle. In Linux, I/O event handles are file descriptors, and signal event handles are signal values.
Event Multiplexer: The arrival of events is random and asynchronous. We cannot predict when the application will receive a client connection request or a pause signal. So the program needs to wait and process events in a loop, which is called an event loop. In an event loop, waiting events are typically implemented using I/O multiplexing techniques. I/O framework libraries generally encapsulate all kinds of I/O multiplexed system calls supported by the system into a unified interface, called event multiplexer. The demultiplex method of the event multiplexer is the core function of waiting for events, and its internal calls are select, poll, epoll_wait and other functions. In addition, the event multi-way distributor needs to implement register_event and remove_event methods for callers to add and remove events from the event multi-way distributor.
Event handlers and time-specific handlers: Event handlers execute business logic corresponding to events. It usually contains one or more handle_event callbacks that are executed in an event loop. An event handler provided by an I/O framework library is usually an interface that users need to inherit to implement their own event handler, i.e., a concrete event handler. Therefore, callback functions in event handlers are generally declared as required functions to support user extensions. In addition, event handlers typically provide a get_handle method that returns the handle associated with the event handler. So what's the relationship between event handlers and handlers? When the Time Multiway Distributor detects that an event has occurred, it notifies the application through a handle. Therefore, we must bind event handlers to handles to get the correct event handler when an event occurs.
Reactor: Reactor is the core of the I/O framework. The main methods it offers are:
handle_events: This method executes an event loop. It repeats the process of waiting for an event and then processing the event handlers for all ready events in turn.
register_handler: This method calls the register_event method of the Event Multiway Distributor to register an event from the Event Multiway Distributor. -remove_handler: This method calls the remove_event method of the event multi-way dispatcher to register an event with the remove event multi-way dispatcher.
Libevent source code analysis
Libevent is a high-performance I/O framework library from the open source community with the following features:
cross-platform support
unified event source
thread-safe
Realization of Reactor Pattern
(Recommended micro-class: Linux micro-class)
one example
Here is a "Hello World" program implemented using the Libevent library.
include #include void signal_cb(int fd, short event, void *argc){ struct event_base* base = (event_base*)argc; struct timeval delay = {2, 0}; printf("Caught an interrupt signal; exiting cleanly in two seconds....\ n"); event_base_loopexit(base, &delay);}void timeout_cb(int fd, short event, void* argc){ printf("timeout\n");}int main(int argc, char const *argv[]){ struct event_base* base = event_base_new(); struct event* signal_event = evsignal_new(base, SIGINT, signal_cb, base); event_add(signal_event, NULL); timeval tv = {1, 0}; struct event* timeout_event = evtimer_new(base, timeout_cb, NULL); event_add(timeout_event, &tv); event_base_dispatch(base); event_free(timeout_event); event_free(signal_event); event_base_free(base); return 0;}
The above code, while simple, basically describes the main logic of the Libevent library:
Call the event_base_new function to create an event_base object. An event_base is equivalent to an instance of Reactor.
Create concrete event handlers and set up Reactor instances to which they belong. evsignal_new and evtimer_new are used to create signal transaction handlers and timed event handlers, respectively.
define evsignal_new(b, x, cb, arg) event_new((b), (x), EV_SIGNAL|EV_PERSIST, (cb), (arg))#define evtimer_new(b, cb, arg) event_new((b), -1, 0, (cb), (arg))
As you can see, their unified entry point is the event_new function, the function used to create a generic event handler, defined as follows:
event_new(struct event_base, evutil_socket_t fd, short events, void (cb)(evutil_socket_t, short, void ), void arg) where the base parameter specifies the row
Of which:
The base parameter specifies the Reactor to which the newly created event handler belongs.
The fd parameter specifies the handle associated with the event handler. When creating an I/O event handler, you should pass a file descriptor to the fd parameter; when creating a signal event handler, you should pass a signal value to the fd parameter, such as SIGINT in the previous instance code; when creating a timed event handler, you should pass-1 to the fd parameter.
The events parameter specifies the event type and is defined as follows:
#define EV_TIMEOUT 0x01 /* timed event */ #define EV_READ 0x02 /* Readable events */ #define EV_WRITE 0x04 /* Write events */ #define EV_SIGNAL 0x08 /* Signal event */ #define EV_PERSIST 0x10 /* Permanent Event */ /* Edge triggered event, requires I/O multiplexing system call support, such as epoll */ #define EV_ET 0x20
In the above code, EV_PERIST's role is to automatically call the event_add function for this event after the event is triggered.
The cb parameter specifies the callback function corresponding to the target event, equivalent to the event handler handle_event method.
arg is the argument that Reactor passes to the callback function.
The event_new function, when successful, returns an object of type event, which is the event handler for Libevent. Libevent uses the word "event" to describe an event handler, not an event, so the convention is as follows:
An event is an event bound to a handle, such as a readable event on file descriptor 0
Event handlers, i.e. objects of event struct type, contain many other members besides the two elements (handle and event type) that an event must have, such as callback functions.
Events are managed by event multipath distributors, and event handlers are managed by event queues, which include a variety of types, such as registered event queues in event_base.
Event Loop Handling of an activated event (ready event) by executing callback functions in the event handler corresponding to the event.
Call the event_add function to add the event handler to the registration event queue and add the event for that event handler to the event multipath dispatcher. The even_add function is equivalent to the register_handler method in Reactor.
Call the event_base_dispatch function to execute an event loop
After the event loop ends, use the *_free series to free system resources
(Recommended course: Linux should learn this)
Source Code Organization
The header file directory includes/event2. This directory was introduced after the Libevent motherboard was upgraded to 2.0 and is provided for use by applications. For example, the event.h header file is the core function, the http.h header file provides HTTP protocol-related services, and the rpc.h header file provides remote procedure call support.
The header file in the source root directory. These header files fall into two categories:
One is the wrapper for some header files in the include/event2 directory
Another category is auxiliary header files for internal use by Libevent, all of which have filenames of the form *-internal.h.
Universal data directory compat/sys. There is only one file in this directory---queue.h. It encapsulates the underlying data structures across platforms, including unidirectional lists, doubly linked lists, queues, tail queues, and circular queues.
Sample directory. Provide some sample code
Test directory. Provide a one-time test code
WIN32-Code。Provides some proprietary code for Windows platforms.
event.c file. The overall framework of the file time Libevent is mainly related to the operations of the event and event_base structures.
debpoll.c, kqueue.c, evport.c, select.c, win32select.c, poll.c, and epoll.c files. They encapsulate the following I/O multiplexing mechanisms: /dev/poll, kqueue, event ports, POSIX select, Windows select, poll, and epoll. The main content of these files is similar, and they are specific implementations of interface functions defined for the structure eventop.
minheap-internal.h: This file implements an event heap to provide support for timed events.
signal.c: Provides support for signals. The content is also a concrete implementation of the interface function defined for the structure eventop
evmap.c file: It maintains the mapping of handles (file descriptors or signals) to time processors
event_taging.c: Provides functions to add tag data, such as a positive number, to the buffer and to read tag data from the buffer
event_iocp file: Provides support for Windows IOCP(Input/Output Completion Port)
buffer*.c file: Provides control over network I/O buffering, including: input and output data filtering, transmission rate limiting, application data protection using SSL (Secure Sockets Layer) protocol, and zero-copy file transmission.
evthread*.c file: provides support for multithreading
listener.c: Encapsulates operations on listening sockets, including listening for connections and accepting connections
logs.c file. It is the log file system of Libevent
evutil.c, evutil_rand.c, strlcpy.c, and arc4random.c files: provide basic operations, such as generating random numbers, obtaining socket address information, reading files, setting socket properties, and so on
evdns.c, http.c and evrpc.c address information: support for DNS protocol, HTTP protocol and RPC protocol respectively
epoll_sub.c file, which is not used
In the whole source code, event-internal.h, include/event2/event_struct.h, event.c and evmap.c are the four most important files. They define the event and event_base structures and implement the operations associated with them.
Read here, this article "Linux high-performance I/O framework library Libevent how to use" article has been introduced, want to master the knowledge of this article also need to practice to understand, if you want to know more about the content of the article, welcome to pay attention to the industry information channel.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.