redis自顶向下源码阅读(二)——服务器初始化

本文深入探讨Redis服务器初始化过程,包括SPT数据结构初始化、setlocale、zmalloc配置、随机种子设定以及服务器配置初始化。重点讲解了SPT的作用以及内存管理的线程安全性。此外,还提及了sentinel模式的判断和服务器配置的初始化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

redis自顶向下源码阅读(二)——服务器初始化

先放出主函数前面一段的代码

int main(int argc, char **argv) {
    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());
    server.sentinel_mode = checkForSentinelMode(argc,argv);
    initServerConfig();
    if (server.sentinel_mode) {
        initSentinelConfig();
        initSentinel();
    }

1. 初始化 SPT 数据结构

  1. 代码

    #ifdef INIT_SETPROCTITLE_REPLACEMENT
        spt_init(argc, argv);
    #endif
    
  2. 含义

    对命令行中的argv字符串数组进行处理,argv的结构如下

     argv[0] argv[1]  environ[0] environ[1]
     a \0    b \0       d=2\0       e=3\0
     0  1    2  3       4567        891011
    

    执行这个函数是因为之后需要设置进程名,即argv[0],但是因为命令行输入进来的argv[]数组在内存上是相邻的,且argv[0]的长度是固定的,那么一旦给argv[0]重新设置,那么字符长度超了怎么办,所以另外开辟了内存,把argv[0]后面的数据存到新开辟的内存地区,所以argv[0]可使用的内存大小相当于进行了一次扩展。其中的argv[1-n]就存到了SPT中。

  3. SPT 结构和 envp

    // setprocitle.c 文件中定义
    extern char **environ;
    
    static struct {
    	/* original value */
    	const char *arg0;
    
    	/* title space available */
    	char *base, *end;
    
    	 /* pointer to original nul character within base */
    	char *nul;
    
    	_Bool reset;
    	int error;
    } SPT;
    
  4. 参考

详情可参考:https://www.jianshu.com/p/36c301ac87df

2. setlocale

    // http://c.biancheng.net/ref/setlocale.html
    setlocale(LC_COLLATE,"");

3. 配置 zmalloc

设置内存分配管理的线程安全变量。

zmalloc_enable_thread_safeness(); 

设置成功后,一旦进行zmalloc相关操作时,程序都会上进程安全锁。例如:

    if (zmalloc_thread_safe) {
#if defined(__ATOMIC_RELAXED) || defined(HAVE_ATOMIC)
        um = update_zmalloc_stat_add(0);
#else
        pthread_mutex_lock(&used_memory_mutex);
        um = used_memory;
        pthread_mutex_unlock(&used_memory_mutex);
#endif
    }

设置内存溢出时的错误处理器

zmalloc_set_oom_handler(redisOutOfMemoryHandler);

4. 配置随机种子

    // 用 时间 和 进程识别码 初始化随机数发生器
    srand(time(NULL)^getpid());
    // 获取时间
    gettimeofday(&tv,NULL);
    // 设置哈希函数的随机种子,哈希的时候用
    dictSetHashFunctionSeed(tv.tv_sec^tv.tv_usec^getpid());

5. 服务器配置初始化

  • 由命令行字符串判断这次启动服务器有没有指定sentinel(哨兵)模式
    // 由命令行字符串判断 有没有
    server.sentinel_mode = checkForSentinelMode(argc,argv);
  • initServerConfig()

  • 初始化 sentinel

      /* 我们现在需要初始化 sentinel,
       * 因为在 sentinel 模式下解析配置文件会
       * 影响到 sentinel 的主节点填充 sentinel 数据结构。
       */
      if (server.sentinel_mode) {
          initSentinelConfig();
          initSentinel();
      }
    

    这两个初始化挺长的,就下一篇讲吧~

总体结构参考:https://www.cnblogs.com/chenpingzhao/p/5229129.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值