I have been studying redis Source Code recently. The efficiency of redis is admirable.
On our Linux machine, the CPU model is,
Intel (r) Pentium (r) CPU g630 @ 2.70 GHz
Intel (r) Pentium (r) CPU g630 @ 2.70 GHz
The set and get operations can reach requests per second. I really admire the efficiency of this Code.
The previous articles mainly introduced the basic code, such as string processing, linked list processing, and hash. This article introduces the core of the network, based on the asynchronous network framework reflected by events.
Asynchronous Network processing is based on epoll. Epoll is divided into two modes: horizontal triggering and edge triggering. The AE uses a horizontal trigger, that is, once there is data, epoll will keep notifying until the read is complete. Edge triggers are only notified once. The notification will not be sent until the status changes. For more information, visit the internet.
1. Structure source code parsing
1.1 read/write event struct
/* File event structure */typedef struct aeFileEvent { int mask; /* one of AE_(READABLE|WRITABLE) */ aeFileProc *rfileProc; aeFileProc *wfileProc; void *clientData;} aeFileEvent;
This struct indicates an event processing function and private data corresponding to FD. This struct will be filled when we want to register an FD time.
1.2 events
/* Time event structure */typedef struct aeTimeEvent { long long id; /* time event identifier. */ long when_sec; /* seconds */ long when_ms; /* milliseconds */ aeTimeProc *timeProc; aeEventFinalizerProc *finalizerProc; void *clientData; struct aeTimeEvent *next;} aeTimeEvent;
When we register scheduled event processing, the corresponding struct will be filled and added to the array.
1.3 trigger FD
/* A fired event */typedef struct aeFiredEvent { int fd; int mask;} aeFiredEvent;
This struct indicates a readable and writable event corresponding to FD.
1.4 total structure of AE events
/* State of an event based program */typedef struct aeEventLoop { int maxfd; /* highest file descriptor currently registered */ int setsize; /* max number of file descriptors tracked */ long long timeEventNextId; time_t lastTime; /* Used to detect system clock skew */ aeFileEvent *events; /* Registered events */ aeFiredEvent *fired; /* Fired events */ aeTimeEvent *timeEventHead; int stop; void *apidata; /* This is used for polling API specific data */ aeBeforeSleepProc *beforesleep;} aeEventLoop;
This struct stores basic data of AE asynchronous events, such as FD size, time event ID, and registered time pointer.
2. AE _epoll Interface
2.1 epoll struct
typedef struct aeApiState { int epfd; struct epoll_event *events;} aeApiState;
Provides epoll variable definitions,
Epfd is created through epoll_create. Events indicates the number of epoll_wait listeners allowed.
Fill in the aeapistate struct.
static int aeApiCreate(aeEventLoop *eventLoop)
Call epoll_wait to obtain the events we care about,
static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp)
2. API
1. Create eventloop
aeEventLoop *aeCreateEventLoop(int setsize)
2. Add events
int aeCreateFileEvent(aeEventLoop *eventLoop, int fd, int mask, aeFileProc *proc, void *clientData)
3. Delete event,
void aeDeleteFileEvent(aeEventLoop *eventLoop, int fd, int mask)
4. Creation Time event
long long aeCreateTimeEvent(aeEventLoop *eventLoop, long long milliseconds, aeTimeProc *proc, void *clientData, aeEventFinalizerProc *finalizerProc)
5. Delete time events
int aeDeleteTimeEvent(aeEventLoop *eventLoop, long long id)
Example
// Create a loop
Proxy. eventloop = aecreateeventloop (default_loop_size );
// Create an event
If (aecreatetimeevent (proxy. eventloop, 1, servercron, null, null) = AE _err)
{
Printf ("can't create the servercron time event \ n ");
Exit (1 );
}
/* The server listens to the connection of the redis client */
Aecreatefileevent (proxy. eventloop, proxy. server_fd, AE _readable, on_client_connected, null );
Aecreatefileevent (proxy. eventloop, proxy. evfd, AE _readable, reconnect_redis, null );
The above is a simple example.
I wrote a redisprox class. I will upload it to you later.