英语老师的大白兔又大又白com233

核心内容摘要

欧美一二三:品味世界的多元魅力
触动感官的极致盛宴:在蜜臀tv,遇见你灵魂深处的渴望

从鸣神大社到荒野巢穴:八重神子“陨落”剧情背后的权力倒置与心理博弈解析

文章目录事件循环线程事件循环相关源码文件事件主循环机制睡眠钩子Hooks机制睡眠钩子的实现Epoll 实战键盘输入监听事件循环线程众所周知Redis 服务器启动时会开启六个线程Thread-1 [redis-server]主线程Thread-2 [bio_close_file]后台 I/O 线程 - 文件关闭Thread-3 [bio_aof]后台 I/O 线程 - AOF 刷盘Thread-4 [bio_lazy_free]后台 I/O 线程 - 惰性删除Thread-5 [jemalloc_bg_thd]内存整理线程Thread-6 [jemalloc_bg_thd]内存整理线程而事件循环则位于Thread-1 [redis-server]主线程中。

事件循环相关源码文件源码文件说明ae.c事件驱动循环核心ae_epoll.cLinux 系统实现epollae_evport.cSolaris 专用ae_kqueue.cmacOS 专用ae_select.c老旧 Linux 或兼容模式使用ebuckets.c事件桶管理eventnotifier.c事件通讯器事件主循环机制Redis 的事件主循环位于ae.c中核心代码如下voidaeMain(aeEventLoop*eventLoop){eventLoop-stop0;while(!eventLoop-stop){aeProcessEvents(eventLoop,AE_ALL_EVENTS|AE_CALL_BEFORE_SLEEP|AE_CALL_AFTER_SLEEP);}}但死循环非常消耗 CPURedis 是如何让线程进入睡眠等待的呢真正的“睡眠”发生在aeApiPoll中其核心是调用系统epoll_waitstaticintaeApiPoll(aeEventLoop*eventLoop,structtimeval*tvp){aeApiState*stateeventLoop-apidata;intretval,numevents0;retvalepoll_wait(state-epfd,state-events,eventLoop-setsize,tvp?(tvp-tv_sec*1000(tvp-tv_usec

/

:-

;if(retval

{intj;numeventsretval;for(j0;jnumevents;j){intmask0;structepoll_event*estate-eventsj;if(e-eventsEPOLLIN)mask|AE_READABLE;if(e-eventsEPOLLOUT)mask|AE_WRITABLE;if(e-eventsEPOLLERR)mask|AE_WRITABLE|AE_READABLE;if(e-eventsEPOLLHUP)mask|AE_WRITABLE|AE_READABLE;eventLoop-fired[j].fde-data.fd;eventLoop-fired[j].maskmask;}}elseif(retval-1errno!EINTR){panic(aeApiPoll: epoll_wait, %s,strerror(errno));}returnnumevents;}epoll_wait就是实现“睡眠”的系统调用。

当没有事件时线程在此阻塞不消耗 CPU。

睡眠钩子Hooks机制为了在睡眠前后执行必要逻辑Redis 提供了钩子函数。

在initServer函数中注册aeSetBeforeSleepProc(server.el, beforeSleep); aeSetAfterSleepProc(server.el, afterSleep);在aeProcessEvents中调用if (eventLoop-beforesleep ! NULL (flags AE_CALL_BEFORE_SLEEP)) eventLoop-beforesleep(eventLoop); if (eventLoop-aftersleep ! NULL flags AE_CALL_AFTER_SLEEP) eventLoop-aftersleep(eventLoop);作用beforeSleep处理客户端写回、检查阻塞超时、计算下一次epoll_wait的超时时间等。

afterSleep清理或重置休眠期间的状态。

这些钩子避免了无限循环中 CPU 空转是 Redis 高效的核心之一。

睡眠钩子的实现beforeSleep钩子和afterSleep钩子的实现都在server.c中分别是void beforeSleep(struct aeEventLoop *eventLoop)和void afterSleep(struct aeEventLoop *eventLoop)。

实现上beforeSleep远比afterSleep复杂。

Epoll 实战键盘输入监听我们可以编写代码练习epoll的使用模拟 Redis 的事件监听机制。

#includestdio.h#includestdlib.h#includesys/epoll.h#includeunistd.h// 简单的错误处理宏#definepanic(fmt,...)\do{fprintf(stderr,FATAL ERROR: fmt (%s:%d)\n,##__VA_ARGS__,__FILE__,__LINE__);\exit(

;}while(

typedefstructepoll_eventEvent;intmain(void){intepfdepoll_create(

;if(epfd

{panic(epoll_create);return1;}// 设置监听标准输入键盘Event ev;ev.eventsEPOLLIN;ev.data.fdSTDIN_FILENO;if(epoll_ctl(epfd,EPOLL_CTL_ADD,STDIN_FILENO,ev)

{panic(epoll_ctl);return1;}Event events[10];charbuf[1024];// 事件循环for(;;){intnfdsepoll_wait(epfd,events,10,-

;if(nfds

{panic(epoll_wait);return1;}// 处理就绪事件for(inti0;infds;i){if(events[i].data.fdSTDIN_FILENO){intnreadread(STDIN_FILENO,buf,sizeof(buf));if(nread

{buf[nread]\0;printf(键盘输入: %s,buf);}}}}close(epfd);return0;}编译运行gcc epoll_test.c -o epoll_test ./epoll_test这个程序会在没有输入时“睡眠”输入内容按回车后被唤醒完美模拟了 Redis 的事件处理模型。

免费已满十八岁在线播放电视剧中国-免费已满十八岁在线播放电视剧中国应用

百度百家号客服电话人工服务

123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123