当前位置:网站首页>redis 网络IO
redis 网络IO
2022-07-27 08:38:00 【芒骁】
redis 网络IO
开门见山,redis直接使用IO多路复用模型中的epoll模型实现和内核的事件传递。
这个过程具体如何实现的,慢慢分析
epoll 源码 linux
https://editor.csdn.net/md/?articleId=121450854
initServer阶段
1. 创建epoll模型实例
创建aeEventLoop server.el = aeCreateEventLoop(server.maxclients+CONFIG_FDSET_INCR)
aeApiCreate(eventLoop)
state->epfd = epoll_create(1024) 创建epoll实例
epoll_create
2. 监听端口 listenToPort
3. 添加文件事件 epoll_ctl 将fd 参数传递到内核
if (aeCreateFileEvent(server.el, server.ipfd[j], AE_READABLE, acceptTcpHandler,NULL) == AE_ERR)
if (aeApiAddEvent(eventLoop, fd, mask) == -1) return AE_ERR
int aeCreateFileEvent(aeEventLoop *eventLoop, int fd, int mask,
aeFileProc *proc, void *clientData)
{
参数:
aeCreateFileEvent(server.el, server.ipfd[j], AE_READABLE, acceptTcpHandler,NULL)
- server.el
- server.ipfd[j]
- AE_READABLE 这里是一个可读事件,所以当可读事件到来,会通过acceptTcpHandler连接处理应答器进行处理
- acceptTcpHandler

aeFileProc 事件处理函数
aeFileProc函数指针定义如下:
typedef void aeFileProc(struct aeEventLoop *eventLoop, int fd, void *clientData, int mask);
在c语言中,回调是通过函数指针实现的。 通过将回调函数地址 传递给 被调函数,从而实现回调。在这里,通过定义函数指针aeFileProc,由调用方实现具体的函数内容,在实际调用函数里,把aeFileProc实现函数的地址传进来。其实相当于定义一种接口,由调用方来实现该接口
aeApiAddEvent

static int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask) {
aeApiState *state = eventLoop->apidata;
struct epoll_event ee = {
0}; /* avoid valgrind warning */
/* If the fd was already monitored for some event, we need a MOD * operation. Otherwise we need an ADD operation. */
* 这里的op表示是添加event还是修改已经存在的event,因为每次通过epoll_ctl 不仅要向内核传递,是一个动作,epollctl支持的动作就三个
* EPOLL_CTL_ADD:表示要进行添加操作。
* EPOLL_CTL_DEL:表示要进行删除操作。
* EPOLL_CTL_MOD:表示要进行修改操作。
int op = eventLoop->events[fd].mask == AE_NONE ?
EPOLL_CTL_ADD : EPOLL_CTL_MOD;
ee.events = 0;
mask |= eventLoop->events[fd].mask; /* Merge old events */
//监控读和写事件,如果mask为可读,设置 ee.events |= EPOLLIN; 0和任何二进制进行或运算 都是二进制位本身相当于ee.events = EPOLLIN
if (mask & AE_READABLE) ee.events |= EPOLLIN;
if (mask & AE_WRITABLE) ee.events |= EPOLLOUT;
//#要监控的fd
ee.data.fd = fd;
//将前面设置好的epfd/op/fd/ee 通过epoll_ctl 设置到kernel space
if (epoll_ctl(state->epfd,op,fd,&ee) == -1) return -1;
return 0;
}
aeEventLoop开始工作 epoll_wait
aeProcessEvents(eventLoop, AE_ALL_EVENTS|AE_CALL_AFTER_SLEEP)
numevents = aeApiPoll(eventLoop, tvp);
aeApiPoll

3:最后通过epoll_wait 来等待event时间的发生。
static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp) {
aeApiState *state = eventLoop->apidata;
int retval, numevents = 0;
#通过epoll_wait 等待epfd事件的发生,这里有设置timeout的时间,在规定的时间内epoll_wait 必须返回
retval = epoll_wait(state->epfd,state->events,eventLoop->setsize,
tvp ? (tvp->tv_sec*1000 + tvp->tv_usec/1000) : -1);
#retval大于0说明是有event发生了,如果是timeout返回则retval等于-1
if (retval > 0) {
int j;
numevents = retval;
#遍历state->events 数据分别找出是读还是写event
for (j = 0; j < numevents; j++) {
int mask = 0;
struct epoll_event *e = state->events+j;
#根据mask 判断是读还是写事件
if (e->events & EPOLLIN) mask |= AE_READABLE;
if (e->events & EPOLLOUT) mask |= AE_WRITABLE;
if (e->events & EPOLLERR) mask |= AE_WRITABLE;
if (e->events & EPOLLHUP) mask |= AE_WRITABLE;
#保持发生event的fd和保存fd对于的mask
eventLoop->fired[j].fd = e->data.fd;
eventLoop->fired[j].mask = mask;
}
}
return numevents;
}
————————————————
版权声明:本文为CSDN博主「tiantao2012」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/tiantao2012/article/details/79527715
边栏推荐
- How to uninstall -- Qianxin secure terminal management system
- [uni app advanced practice] take you hand-in-hand to learn the development of a purely practical complex project 1/100
- Function realization of order system
- 众昂矿业:新能源行业快速发展,氟化工产品势头强劲
- Containerd failed to pull private database image (kubelet)
- UVM入门实验1
- 693. 行程排序
- Login to homepage function implementation
- 海关总署:这类产品暂停进口
- QPushButton 按钮的创建与简单应用
猜你喜欢

开怀一笑

OSI seven layer model and tcp/ip four layer (TCP and UDP) (notes)

Fluent rendering mechanism - GPU thread rendering

Breadth first search

第2章 前台数据展现

Solution to the program design of the sequence structure of one book (Chapter 1)

Minio 安装与使用

Login to homepage function implementation

It's better to be full than delicious; It's better to be drunk than drunk

Alibaba cloud international receipt message introduction and configuration process
随机推荐
Using ecological power, opengauss breaks through the performance bottleneck
海关总署:这类产品暂停进口
Background order management
Is online account opening safe? Want to know how securities companies get preferential accounts?
Vcenter7.0 managing esxi7.0 hosts
First experience of tryme in opengauss
3428. 放苹果
Installation and use of Supervisor
Block, there is a gap between the block elements in the row
Use of elastic box / expansion box (Flex)
Chapter 2 foreground data display
带宽 与 货币
OPPO 自研大规模知识图谱及其在数智工程中的应用
4277. 区块反转
Cenos7 update MariaDB
Flask project configuration
All in one 1329 cells (breadth first search)
Implementation of adding function of background user management display
ROS2安装时出现Connection failed [IP: 91.189.91.39 80]
Vcenter7.0 installation of ibm3650m4 physical machine