近期學習了redis底層框架,好多東西以前都沒據說過,算是大開眼界了。redis
先梳理下redis正常的通信流程吧安全
首先服務器啓動都有主函數main,這個main函數就在redis.c裏服務器
首先是initserverconfig(),在這裏初始化了redisserver基本的配置信息,微信
接着調用loadServerConfig(char *filename) 對 server 全局變量從新初始化。多線程
而後是調用daemonize(),實現守護進程,脫離了控制檯,是這個進程框架
成爲獨立的首領進程函數
接下來是initServer(),這個過程很重要,完成了事件驅動的註冊和一些oop
回調函數的綁定,回頭仔細說這個函數裏面的功能學習
初始化服務器事後aeSetBeforeSleepProc(),設置了服務器休眠以前會編碼
調用beforeSleep函數
而後進入主要的事件輪詢函數 aeMain(server.el),在這裏完成事件的派發
最後事件輪詢事後咱們調用aeDeleteEventLoop,釋放以前開闢的內存,
結束進程。
中間略去一些瑣碎的過程,咱們總結一下
initserverconfig() ----> loadServerConfig------> daemonize()
initServer()-----> aeSetBeforeSleepProc()------>aeMain()----->
aeDeleteEventLoop
接下來詳細說一下每個步驟都作了什麼。
看一下main()函數
int main(int argc, char **argv) {
//設置時間,通常都是設置事件poll等待多長時間返回
struct timeval tv;
/* We need to initialize our libraries, and the server configuration. */
#ifdef INIT_SETPROCTITLE_REPLACEMENT
//進程重命名
spt_init(argc, argv);
#endif
//好像是更改字符編碼
setlocale(LC_COLLATE,"");
//設置多線程安全模式
zmalloc_enable_thread_safeness();
//註冊內存使用過量報錯的函數
zmalloc_set_oom_handler(redisOutOfMemoryHandler);
srand(time(NULL)^getpid());
gettimeofday(&tv,NULL);
//哈希種子
dictSetHashFunctionSeed(tv.tv_sec^tv.tv_usec^getpid());
//服務器的啓動模式:單機模式、Cluster模式、sentinel模式
server.sentinel_mode = checkForSentinelMode(argc,argv);
initServerConfig();
loadServerConfig(configfile,options);
。。。
//建立守護進程
if (server.daemonize) daemonize();
//初始化服務器
initServer();
//設置服務器sleep以前的函數調用
aeSetBeforeSleepProc(server.el,beforeSleep);
//主函數事件驅動
aeMain(server.el);
//刪除事件循環的結構,釋放空間
aeDeleteEventLoop(server.el);
return 0;
}
微信訂閱號