设为首页 加入收藏

TOP

redis启动过程源码解析(一)
2019-09-17 18:41:58 】 浏览:79
Tags:redis 启动 过程 源码 解析

  redis整个程序的入口函数在server.c中的main函数,函数调用关系如下图1,调用顺序为从上到下,从左至右。

图1 redis启动函数调用图

  main函数源码如下,1-55行根据配置文件和启动命令参数设置全局对象server ,57-59设置redis的服务器端为后台进程, initServer主要提前创建一些经常用到的对象用于节约内存,根据设置的ip地址和端口创建监听套接字用于客户端连接,并初始化时间事件,64行用于设置server->el ->beforesleep = beforesleep,aeMain函数是个循环函数,用于监听客户端连接,接收客户端命令并进行处理等。

 1 //整个程序的入口函数
 2 int main(int argc, char **argv) {
 3     //初始化服务器配置,设置全局对象server的状态
 4     initServerConfig();
 5 
 6     /* Store the executable path and arguments in a safe place in order
 7      * to be able to restart the server later. */
 8     //存储运行命令的绝对路径及运行参数
 9     server.executable = getAbsolutePath(argv[0]);
10     server.exec_argv = zmalloc(sizeof(char*)*(argc+1));
11     server.exec_argv[argc] = NULL;
12     for (j = 0; j < argc; j++) server.exec_argv[j] = zstrdup(argv[j]);
13 
14     if (argc >= 2) {
15         j = 1; /* First option to parse in argv[] */
16         sds options = sdsempty();
17         char *configfile = NULL;
18 
19         //命令指定了配置文件,对配置文件做处理,配置文件跟在程序名后第一位
20         /* First argument is the config file name? */
21         if (argv[j][0] != '-' || argv[j][1] != '-') {
22             configfile = argv[j];
23             server.configfile = getAbsolutePath(configfile);
24             /* Replace the config file in server.exec_argv with
25              * its absolute path. */
26             zfree(server.exec_argv[j]);
27             server.exec_argv[j] = zstrdup(server.configfile);
28             j++;
29         }
30 
31         /* All the other options are parsed and conceptually appended to the
32          * configuration file. For instance --port 6380 will generate the
33          * string "port 6380\n" to be parsed after the actual file name
34          * is parsed, if any. */
35         while(j != argc) {//解析除配置文件外的其它参数
36             if (argv[j][0] == '-' && argv[j][1] == '-') {
37                 /* Option name */
38                 if (!strcmp(argv[j], "--check-rdb")) {
39                     /* Argument has no options, need to skip for parsing. */
40                     j++;
41                     continue;
42                 }
43                 if (sdslen(options)) options = sdscat(options,"\n");
44                 options = sdscat(options,argv[j]+2);//去掉参数前面的--
45                 options = sdscat(options," ");//参数对应的值和参数名应" "分隔
46             } else {
47                 /* Option argument */
48                 options = sdscatrepr(options,argv[j],strlen(argv[j]));
49                 options = sdscat(options," ");
50             }
51             j++;
52         }
53         //从指定配置文件和命令选项设置服务器对象server参数,覆盖默认配置
54         loadServerConfig(configfile,options);
55     }
56 
57     server.supervised = redisIsSupervised(server.supervised_mode);
58     int background = server.daemonize && !server.supervised;
59     if (background) daemonize();//后台进程模式
60 
61     //初始化服务器功能,包括时间事件1ms调用serverCron,文件事件(套接字可读可写时的处理函数),集群初始化等
62     initServer();
63     aeSetBeforeSleepProc(server.el,beforeSleep);//设置beforeSleep事件处理函数
64     aeSetAfterSleepProc(server.el,afterSleep);//设置aftersleep事件处理函数
65     aeMain(server.el);//循环,接受客户端连接,处理命令等
66     aeDeleteEventLoop(server.el);//退出循环,删除事件处理
67     return 0;
68 }

  initServer函数源码如下,主要对server中的变量进行初始化,其中listenToPort根据监听的地址和端口, 设置server.ipfd(监听套接字数组)和server.ipfd_count(监听套接字数目),85行aeCreateTimeEvent设置定时器事件,每1ms执行serverCron函数,94行aeCreateFileEvent函数设置监听套接字有客户端连接时执行的事件处理函数acceptTcpHandler。

  1 void initServer(void) {
  2     int j;
  3     server.hz = server.config_hz;
  4     server.pid = getpid();
  5     server.current_client = NULL;
  6     server.clients = listCreate();
  7     server.clients_index = raxNew();
  8     server.clients_to_close = listCreate();
  9     server.slaves = li
首页 上一页 1 2 3 4 下一页 尾页 1/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇CentOS7.3安装mysql数据库 下一篇DBA_OBJECTS

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目