日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > 数据库 >内容正文

数据库

Redis事件管理(三)

發(fā)布時(shí)間:2025/4/9 数据库 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Redis事件管理(三) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

?Redis的事件管理和定時(shí)器的管理都是自己來(lái)實(shí)現(xiàn)的,Redis的事件管理分為兩部分,一部分是封裝了系統(tǒng)的異步事件API,還有一部分是在這基礎(chǔ)上封裝了一個(gè)通用的事件管理器,根據(jù)具體的系統(tǒng)來(lái)決定具體使用哪個(gè)異步管理API。

先來(lái)說(shuō)說(shuō)Redis支持哪些異步的系統(tǒng)API。Redis內(nèi)部封裝了epoll,evport,kqueue,select這四個(gè)原始的事件管理器。

那epoll舉個(gè)例子解析一下吧。

1 typedef struct aeApiState 2 { 3 int epfd; //文件描述符 4 struct epoll_event *events;//epoll實(shí)例 5 } aeApiState;

這個(gè)結(jié)構(gòu)體封裝了一個(gè)具體的事件實(shí)例。

封裝的接口函數(shù):

1 static int aeApiCreate(aeEventLoop *eventLoop) //創(chuàng)建一個(gè)事件管理器 2 static int aeApiResize(aeEventLoop *eventLoop, int setsize) //重置事件管理器管理事件的個(gè)數(shù) 3 static void aeApiFree(aeEventLoop *eventLoop) //刪除一個(gè)事件管理器 4 static int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask)//向事件管理器中添加一個(gè)事件 5 static void aeApiDelEvent(aeEventLoop *eventLoop, int fd, int delmask) //從時(shí)間管理器中刪除一個(gè)事件 6 static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp)//激活事件管理器,返回已經(jīng)觸發(fā)的事件的個(gè)數(shù) 7 static char *aeApiName(void) //獲取當(dāng)前使用的是什么事件模型 1 static int aeApiCreate(aeEventLoop *eventLoop) //創(chuàng)建一個(gè)事件管理器 1 /*創(chuàng)建成功返回0,否則返回-1*/ 2 static int aeApiCreate(aeEventLoop *eventLoop) 3 { 4 aeApiState *state = zmalloc(sizeof(aeApiState)); 5 6 if (!state) return -1; 7 /*直接按size申請(qǐng)內(nèi)存*/ 8 state->events = zmalloc(sizeof(struct epoll_event) * eventLoop->setsize); 9 /*事件內(nèi)存失敗時(shí)要釋放結(jié)構(gòu)體的內(nèi)存,防止出現(xiàn)內(nèi)存泄露*/ 10 if (!state->events) 11 { 12 zfree(state); 13 return -1; 14 } 15 /*創(chuàng)建epoll描述符,如果創(chuàng)建失敗,記得把上面申請(qǐng)的內(nèi)存釋放掉*/ 16 state->epfd = epoll_create(1024); /* 1024 is just a hint for the kernel */ 17 if (state->epfd == -1) 18 { 19 zfree(state->events); 20 zfree(state); 21 return -1; 22 } 23 eventLoop->apidata = state; 24 return 0; 25 } 2 static int aeApiResize(aeEventLoop *eventLoop, int setsize) //重置事件管理器管理事件的個(gè)數(shù) /*重置可接受事件的個(gè)數(shù),這個(gè)函數(shù)不能直接調(diào)用,因?yàn)闆](méi)有檢查新size和舊size的大小關(guān)系,如果小了,直接重置會(huì)出問(wèn)題*/ static int aeApiResize(aeEventLoop *eventLoop, int setsize) {aeApiState *state = eventLoop->apidata;state->events = zrealloc(state->events, sizeof(struct epoll_event)*setsize);return 0; } 4 static int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask)//向事件管理器中添加一個(gè)事件 1 /*向epoll中增加事件,需要注冊(cè)新的文件描述符和需要監(jiān)控的事件類型*/ 2 static int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask) 3 { 4 aeApiState *state = eventLoop->apidata; 5 struct epoll_event ee; 6 /*因?yàn)閑poll的維護(hù)是用數(shù)組維護(hù)的,通過(guò)下標(biāo)的方式可以直接訪問(wèn),省時(shí)省力。如果這個(gè)節(jié)點(diǎn)已經(jīng)激活了,那新事件添加就好了*/ 7 int op = eventLoop->events[fd].mask == AE_NONE ? EPOLL_CTL_ADD : EPOLL_CTL_MOD; 8 9 ee.events = 0; 10 mask |= eventLoop->events[fd].mask; /* Merge old events */ 11 if (mask & AE_READABLE) ee.events |= EPOLLIN; 12 if (mask & AE_WRITABLE) ee.events |= EPOLLOUT; 13 ee.data.u64 = 0; /* avoid valgrind warning */ 14 ee.data.fd = fd; 15 if (epoll_ctl(state->epfd,op,fd,&ee) == -1) return -1; 16 return 0; 17 } 6 static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp)//激活事件管理器,返回已經(jīng)觸發(fā)的事件的個(gè)數(shù) /*獲取事件隊(duì)列*/ static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp) {aeApiState *state = eventLoop->apidata;int retval, numevents = 0;retval = epoll_wait(state->epfd,state->events,eventLoop->setsize,tvp ? (tvp->tv_sec*1000 + tvp->tv_usec/1000) : -1);if (retval > 0) {int j;numevents = retval;/*將滿足條件的文件描述符和狀態(tài)保存到fired中,后期逐個(gè)處理*/for (j = 0; j < numevents; j++) {int mask = 0;struct epoll_event *e = state->events+j;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;eventLoop->fired[j].fd = e->data.fd;eventLoop->fired[j].mask = mask;}}return numevents; }

?

轉(zhuǎn)載于:https://www.cnblogs.com/likui360/p/5297729.html

總結(jié)

以上是生活随笔為你收集整理的Redis事件管理(三)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。