Libevent source code analysis time management and timer

I. Overview

Libevent provides a high-performance timer function to facilitate the execution of delayed callback logic.

2. Basic realization principle

When adding event monitoring, you don't need to specify fd and monitored events, and specify the timeout period to implement the timer function.
The underlying implementation of the timer consists of two parts:

  • Minimum heap: It is constructed according to the timeout period of the event, and the earliest timeout period is at the top of the heap.
  • Universal timeout queue: This can personalize the timeout time of each queue. When adding events, they will be placed in the same queue at the same time, and only one event at the head of the queue will be added to the smallest heap in the smallest heap. It can avoid the problem that a large number of events are placed in the smallest heap, resulting in poor performance when the smallest heap is added or deleted.

Three, minimum heap implementation

The implementation of the minimum heap uses a typical array to maintain. When the array elements are full, the array is expanded and the minimum heap is adjusted.
Insert picture description here

Four, public timeout queue

1. The user can customize the timeout time of each public timeout queue, and the timeout time when each timeout queue joins is the same, which ensures that the time in the same queue will time out according to the time when joining the queue. This avoids maintaining a large number of events in the smallest heap, and only needs to add a timeout event to the smallest heap.
2. The structure of the public timeout queue is defined as follows:

struct common_timeout_list {
    
    
struct event_list events; //事件列表
struct timeval duration; //duration表示加入到这个队列里时,都是duration的超时时间
struct event timeout_event; //每个common_timout_list,都会在超时最小堆里放一个超时事件,等timeout_event超时时,检查events里的哪些事件超时,并再往最小堆里加入一个超时事件。
struct event_base *base; //所属的event_base
};

3. The specific implementation principle is as follows:
Insert picture description here
each queue is a doubly linked list
Insert picture description here

Five, timer use example

	struct event timeout;
	struct timeval tv;
	struct event_base *base;
	int flags = 0; //0表示只执行一次,EV_PERSIST表示定时器超时后继续等待超时

	/* Initalize the event library */
	base = event_base_new();

	/* Initalize one event */
	event_assign(&timeout, base, -1, flags, timeout_cb, (void*) &timeout);

	evutil_timerclear(&tv);
	tv.tv_sec = 2;
	event_add(&timeout, &tv);

	evutil_gettimeofday(&lasttime, NULL);

	event_base_dispatch(base);

Guess you like

Origin blog.csdn.net/gamekit/article/details/113101356