深入redis内部--初始化服务器

初始化服务器代码如下:

signal(SIGHUP,SIG_IGN); signal(SIGPIPE,SIG_IGN); setupSignalHandlers(); </span><span style="color: #0000ff;"&gt;if</span><span style="color: #000000;"&gt; (server.syslog_enabled) { openlog(server.syslog_ident,LOG_PID </span>| LOG_NDELAY |<span style="color: #000000;"&gt; LOG_NOWAIT,server.syslog_facility); } server.current_client </span>=<span style="color: #000000;"&gt; NULL; server.clients </span>=<span style="color: #000000;"&gt; listCreate(); //创建客户队列 server.clients_to_close </span>=<span style="color: #000000;"&gt; listCreate(); //创建将关闭的客户队列 server.slaves </span>=<span style="color: #000000;"&gt; listCreate(); //创建从机队列 server.monitors </span>=<span style="color: #000000;"&gt; listCreate(); //创建监控队列 server.slaveseldb </span>= -<span style="color: #800080;"&gt;1</span>; <span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; Force to emit the first SELECT command. </span><span style="color: #008000;"&gt;*/</span><span style="color: #000000;"&gt; server.unblocked_clients </span>=<span style="color: #000000;"&gt; listCreate(); //创建非堵塞客户队列 server.ready_keys </span>=<span style="color: #000000;"&gt; listCreate(); //创建可读key队列 createSharedObjects(); // 创建共享对象 adjustOpenFilesLimit(); //改变可打开文件的最大数量 server.el </span>= aeCreateEventLoop(server.maxclients+<span style="color: #000000;"&gt;REDIS_EVENTLOOP_FDSET_INCR); //创建事件处理 server.db </span>= zmalloc(<span style="color: #0000ff;"&gt;sizeof</span>(redisDb)*<span style="color: #000000;"&gt;server.dbnum); //分别db内存 </span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; Open the TCP listening socket for the user commands. </span><span style="color: #008000;"&gt;*/</span> <span style="color: #0000ff;"&gt;if</span> (listenToPort(server.port,server.ipfd,&amp;server.ipfd_count) ==<span style="color: #000000;"&gt; REDIS_ERR) //监听端口 exit(</span><span style="color: #800080;"&gt;1</span><span style="color: #000000;"&gt;); </span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; Open the listening Unix domain socket. </span><span style="color: #008000;"&gt;*/</span> <span style="color: #0000ff;"&gt;if</span> (server.unixsocket !=<span style="color: #000000;"&gt; NULL) { unlink(server.unixsocket); </span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; don't care if this fails </span><span style="color: #008000;"&gt;*/</span><span style="color: #000000;"&gt; server.sofd </span>=<span style="color: #000000;"&gt; anetUnixServer(server.neterr,server.unixsocket,server.unixsocketperm); </span><span style="color: #0000ff;"&gt;if</span> (server.sofd ==<span style="color: #000000;"&gt; ANET_ERR) { redisLog(REDIS_WARNING,</span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;Opening socket: %s</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;,server.neterr); exit(</span><span style="color: #800080;"&gt;1</span><span style="color: #000000;"&gt;); } } </span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; Abort if there are no listening sockets at all. </span><span style="color: #008000;"&gt;*/</span> <span style="color: #0000ff;"&gt;if</span> (server.ipfd_count == <span style="color: #800080;"&gt;0</span> &amp;&amp; server.sofd < <span style="color: #800080;"&gt;0</span><span style="color: #000000;"&gt;) { redisLog(REDIS_WARNING,</span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;Configured to not listen anywhere,exiting.</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;); exit(</span><span style="color: #800080;"&gt;1</span><span style="color: #000000;"&gt;); } </span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; Create the Redis databases,and initialize other internal state. </span><span style="color: #008000;"&gt;*/</span> <span style="color: #0000ff;"&gt;for</span> (j = <span style="color: #800080;"&gt;0</span>; j < server.dbnum; j++<span style="color: #000000;"&gt;) { server.db[j].dict </span>= dictCreate(&amp;<span style="color: #000000;"&gt;dbDictType,NULL); server.db[j].expires </span>= dictCreate(&amp;<span style="color: #000000;"&gt;keyptrDictType,NULL); server.db[j].blocking_keys </span>= dictCreate(&amp;<span style="color: #000000;"&gt;keylistDictType,NULL); server.db[j].ready_keys </span>= dictCreate(&amp;<span style="color: #000000;"&gt;setDictType,NULL); server.db[j].watched_keys </span>= dictCreate(&amp;<span style="color: #000000;"&gt;keylistDictType,NULL); server.db[j].id </span>=<span style="color: #000000;"&gt; j; server.db[j].avg_ttl </span>= <span style="color: #800080;"&gt;0</span><span style="color: #000000;"&gt;; } server.pubsub_channels </span>= dictCreate(&amp;<span style="color: #000000;"&gt;keylistDictType,NULL); server.pubsub_patterns </span>=<span style="color: #000000;"&gt; listCreate(); listSetFreeMethod(server.pubsub_patterns,freePubsubPattern); listSetMatchMethod(server.pubsub_patterns,listMatchPubsubPattern); server.cronloops </span>= <span style="color: #800080;"&gt;0</span><span style="color: #000000;"&gt;; server.rdb_child_pid </span>= -<span style="color: #800080;"&gt;1</span><span style="color: #000000;"&gt;; server.aof_child_pid </span>= -<span style="color: #800080;"&gt;1</span><span style="color: #000000;"&gt;; aofRewriteBufferReset(); server.aof_buf </span>=<span style="color: #000000;"&gt; sdsempty(); server.lastsave </span>= time(NULL); <span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; At startup we consider the DB saved. </span><span style="color: #008000;"&gt;*/</span><span style="color: #000000;"&gt; server.lastbgsave_try </span>= <span style="color: #800080;"&gt;0</span>; <span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; At startup we never tried to BGSAVE. </span><span style="color: #008000;"&gt;*/</span><span style="color: #000000;"&gt; server.rdb_save_time_last </span>= -<span style="color: #800080;"&gt;1</span><span style="color: #000000;"&gt;; server.rdb_save_time_start </span>= -<span style="color: #800080;"&gt;1</span><span style="color: #000000;"&gt;; server.dirty </span>= <span style="color: #800080;"&gt;0</span><span style="color: #000000;"&gt;; server.stat_numcommands </span>= <span style="color: #800080;"&gt;0</span><span style="color: #000000;"&gt;; server.stat_numconnections </span>= <span style="color: #800080;"&gt;0</span><span style="color: #000000;"&gt;; server.stat_expiredkeys </span>= <span style="color: #800080;"&gt;0</span><span style="color: #000000;"&gt;; server.stat_evictedkeys </span>= <span style="color: #800080;"&gt;0</span><span style="color: #000000;"&gt;; server.stat_starttime </span>=<span style="color: #000000;"&gt; time(NULL); server.stat_keyspace_misses </span>= <span style="color: #800080;"&gt;0</span><span style="color: #000000;"&gt;; server.stat_keyspace_hits </span>= <span style="color: #800080;"&gt;0</span><span style="color: #000000;"&gt;; server.stat_peak_memory </span>= <span style="color: #800080;"&gt;0</span><span style="color: #000000;"&gt;; server.stat_fork_time </span>= <span style="color: #800080;"&gt;0</span><span style="color: #000000;"&gt;; server.stat_rejected_conn </span>= <span style="color: #800080;"&gt;0</span><span style="color: #000000;"&gt;; server.stat_sync_full </span>= <span style="color: #800080;"&gt;0</span><span style="color: #000000;"&gt;; server.stat_sync_partial_ok </span>= <span style="color: #800080;"&gt;0</span><span style="color: #000000;"&gt;; server.stat_sync_partial_err </span>= <span style="color: #800080;"&gt;0</span><span style="color: #000000;"&gt;; memset(server.ops_sec_samples,</span><span style="color: #800080;"&gt;0</span>,<span style="color: #0000ff;"&gt;sizeof</span><span style="color: #000000;"&gt;(server.ops_sec_samples)); server.ops_sec_idx </span>= <span style="color: #800080;"&gt;0</span><span style="color: #000000;"&gt;; server.ops_sec_last_sample_time </span>=<span style="color: #000000;"&gt; mstime(); server.ops_sec_last_sample_ops </span>= <span style="color: #800080;"&gt;0</span><span style="color: #000000;"&gt;; server.unixtime </span>=<span style="color: #000000;"&gt; time(NULL); server.mstime </span>=<span style="color: #000000;"&gt; mstime(); server.lastbgsave_status </span>=<span style="color: #000000;"&gt; REDIS_OK; server.repl_good_slaves_count </span>= <span style="color: #800080;"&gt;0</span><span style="color: #000000;"&gt;; </span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; Create the serverCron() time event,that's our main way to process * background operations. </span><span style="color: #008000;"&gt;*/</span> <span style="color: #0000ff;"&gt;if</span>(aeCreateTimeEvent(server.el,<span style="color: #800080;"&gt;1</span>,serverCron,NULL,NULL) ==<span style="color: #000000;"&gt; AE_ERR) { redisPanic(</span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;Can't create the serverCron time event.</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;); exit(</span><span style="color: #800080;"&gt;1</span><span style="color: #000000;"&gt;); } </span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; Create an event handler for accepting new connections in TCP and Unix * domain sockets. </span><span style="color: #008000;"&gt;*/</span> <span style="color: #0000ff;"&gt;for</span> (j = <span style="color: #800080;"&gt;0</span>; j < server.ipfd_count; j++<span style="color: #000000;"&gt;) { </span><span style="color: #0000ff;"&gt;if</span><span style="color: #000000;"&gt; (aeCreateFileEvent(server.el,server.ipfd[j],AE_READABLE,acceptTcpHandler,NULL) </span>==<span style="color: #000000;"&gt; AE_ERR) { redisPanic( </span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;Unrecoverable error creating server.ipfd file event.</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;); } } </span><span style="color: #0000ff;"&gt;if</span> (server.sofd > <span style="color: #800080;"&gt;0</span> &amp;&amp;<span style="color: #000000;"&gt; aeCreateFileEvent(server.el,server.sofd,acceptUnixHandler,NULL) </span>== AE_ERR) redisPanic(<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;Unrecoverable error creating server.sofd file event.</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;); </span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; Open the AOF file if needed. </span><span style="color: #008000;"&gt;*/</span> <span style="color: #0000ff;"&gt;if</span> (server.aof_state ==<span style="color: #000000;"&gt; REDIS_AOF_ON) { server.aof_fd </span>=<span style="color: #000000;"&gt; open(server.aof_filename,O_WRONLY</span>|O_APPEND|O_CREAT,<span style="color: #800080;"&gt;0644</span><span style="color: #000000;"&gt;); </span><span style="color: #0000ff;"&gt;if</span> (server.aof_fd == -<span style="color: #800080;"&gt;1</span><span style="color: #000000;"&gt;) { redisLog(REDIS_WARNING,</span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;Can't open the append-only file: %s</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;,strerror(errno)); exit(</span><span style="color: #800080;"&gt;1</span><span style="color: #000000;"&gt;); } } </span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; 32 bit instances are limited to 4GB of address space,so if there is * no explicit limit in the user provided configuration we set a limit * at 3 GB using maxmemory with 'noeviction' policy'. This avoids * useless crashes of the Redis instance for out of memory. </span><span style="color: #008000;"&gt;*/</span> <span style="color: #0000ff;"&gt;if</span> (server.arch_bits == <span style="color: #800080;"&gt;32</span> &amp;&amp; server.maxmemory == <span style="color: #800080;"&gt;0</span><span style="color: #000000;"&gt;) { redisLog(REDIS_WARNING,</span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;Warning: 32 bit instance detected but no memory limit set. Setting 3 GB maxmemory limit with 'noeviction' policy now.</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;); server.maxmemory </span>= 3072LL*(<span style="color: #800080;"&gt;1024</span>*<span style="color: #800080;"&gt;1024</span>); <span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; 3 GB </span><span style="color: #008000;"&gt;*/</span><span style="color: #000000;"&gt; server.maxmemory_policy </span>=<span style="color: #000000;"&gt; REDIS_MAXMEMORY_NO_EVICTION; } replicationScriptCacheInit(); scriptingInit(); slowlogInit(); bioInit();

}

1.1 信号处理

signal语法:

#include

<span style="color: #0000ff;">void (signal(<span style="color: #0000ff;">int sig,<span style="color: #0000ff;">void (func)(<span style="color: #0000ff;">int)))(<span style="color: #0000ff;">int<span style="color: #000000;">);
<span style="color: #0000ff;">int sighold(<span style="color: #0000ff;">int<span style="color: #000000;"> sig);
<span style="color: #0000ff;">int sigignore(<span style="color: #0000ff;">int<span style="color: #000000;"> sig);
<span style="color: #0000ff;">int sigpause(<span style="color: #0000ff;">int<span style="color: #000000;"> sig);
<span style="color: #0000ff;">int sigrelse(<span style="color: #0000ff;">int<span style="color: #000000;"> sig);
<span style="color: #0000ff;">void (sigset(<span style="color: #0000ff;">int sig,<span style="color: #0000ff;">void (disp)(<span style="color: #0000ff;">int)))(<span style="color: #0000ff;">int);

signal变量定义在signal.h文件中,其中:

1.信号

Signal

Description

SIGABRT

由调用abort函数产生,进程非正常退出

SIGALRM

用alarm函数设置的timer超时或setitimer函数设置的interval timer超时

SIGBUS

某种特定的硬件异常,通常由内存访问引起

SIGCANCEL

由Solaris Thread Library内部使用,通常不会使用

SIGCHLD

进程Terminate或Stop的时候,SIGCHLD会发送给它的父进程。缺省情况下该Signal会被忽略

SIGCONT

当被stop的进程恢复运行的时候,自动发送

SIGEMT

和实现相关的硬件异常

SIGFPE

数学相关的异常,如被0除,浮点溢出,等等

SIGFREEZE

Solaris专用,Hiberate或者Suspended时候发送

SIGILL

非法指令异常

SIGINFO

BSD signal。由Status Key产生,通常是CTRL+T。发送给所有Foreground Group的进程

SIGINT

由Interrupt Key产生,通常是CTRL+C或者DELETE。发送给所有ForeGround Group的进程

SIGIO

异步IO事件

SIGIOT

实现相关的硬件异常,一般对应SIGABRT

SIGKILL

无法处理和忽略。中止某个进程

SIGLWP

由Solaris Thread Libray内部使用

SIGPOLL

当某个事件发送给Pollable Device的时候发送

SIGPROF

Setitimer指定的Profiling Interval Timer所产生

SIGPWR

和系统相关。和UPS相关。

SIGQUIT

输入Quit Key的时候(CTRL+/)发送给所有Foreground Group的进程

SIGSEGV

非法内存访问

SIGSTKFLT

Linux专用,数学协处理器的栈异常

SIGSTOP

中止进程。无法处理和忽略。

SIGSYS

非法系统调用

SIGTERM

请求中止进程,kill命令缺省发送

SIGTHAW

Solaris专用,从Suspend恢复时候发送

SIGTRAP

实现相关的硬件异常。一般是调试异常

SIGTSTP

Suspend Key,一般是Ctrl+Z。发送给所有Foreground Group的进程

SIGTTIN

当Background Group的进程尝试读取Terminal的时候发送

SIGTTOU

当Background Group的进程尝试写Terminal的时候发送

SIGURG

当out-of-band data接收的时候可能发送

SIGUSR1

用户自定义signal 1

SIGUSR2

用户自定义signal 2

SIGVTALRM

setitimer函数设置的Virtual Interval Timer超时的时候

SIGWAITING

Solaris Thread Library内部实现专用

SIGWINCH

当Terminal的窗口大小改变的时候,发送给Foreground Group的所有进程

SIGXCPU

当CPU时间限制超时的时候

SIGXFSZ

进程超过文件大小限制

SIGXRES

Solaris专用,进程超过资源限制的时候发送

================================================================

      2.处理函数

         SIG_DFL
      Request for default signal handling.
         SIG_ERR
      Return value from in case of error.
         SIG_HOLD
      Request that signal be held.
.

      3. 建立信号处理函数

setupSignalHandlers(</span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; When the SA_SIGINFO flag is set in sa_flags then sa_sigaction is used. * Otherwise,sa_handler is used. </span><span style="color: #008000;"&gt;*/</span><span style="color: #000000;"&gt; sigemptyset(</span>&amp;<span style="color: #000000;"&gt;act.sa_mask); act.sa_flags </span>= <span style="color: #800080;"&gt;0</span><span style="color: #000000;"&gt;; act.sa_handler </span>=<span style="color: #000000;"&gt; sigtermHandler; //信号中断处理函数,使用 sigaction(SIGTERM,&amp;act,NULL); sigaction(SIGTERM,</span>&amp;<span style="color: #000000;"&gt;act,NULL);

ifdef HAVE_BACKTRACE

sigemptyset(</span>&amp;<span style="color: #000000;"&gt;act.sa_mask);
act.sa_flags </span>= SA_NODEFER | SA_RESETHAND |<span style="color: #000000;"&gt; SA_SIGINFO;
act.sa_sigaction </span>=<span style="color: #000000;"&gt; sigsegvHandler;
sigaction(SIGSEGV,NULL);
sigaction(SIGBUS,NULL);
sigaction(SIGFPE,NULL);
sigaction(SIGILL,NULL);

<span style="color: #0000ff;">#endif
<span style="color: #0000ff;">return<span style="color: #000000;">;
}

1.2 创建共享对象

createSharedObjects(shared.crlf </span>= createObject(REDIS_STRING,sdsnew(<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;\r\n</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;)); shared.ok </span>= createObject(REDIS_STRING,sdsnew(<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;+OK\r\n</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;)); shared.err </span>= createObject(REDIS_STRING,sdsnew(<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;-ERR\r\n</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;)); shared.emptybulk </span>= createObject(REDIS_STRING,sdsnew(<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;$0\r\n\r\n</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;)); shared.czero </span>= createObject(REDIS_STRING,sdsnew(<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;:0\r\n</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;)); shared.cone </span>= createObject(REDIS_STRING,sdsnew(<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;:1\r\n</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;)); shared.cnegone </span>= createObject(REDIS_STRING,sdsnew(<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;:-1\r\n</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;)); shared.nullbulk </span>= createObject(REDIS_STRING,sdsnew(<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;$-1\r\n</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;)); shared.nullmultibulk </span>= createObject(REDIS_STRING,sdsnew(<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;*-1\r\n</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;)); shared.emptymultibulk </span>= createObject(REDIS_STRING,sdsnew(<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;*0\r\n</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;)); shared.pong </span>= createObject(REDIS_STRING,sdsnew(<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;+PONG\r\n</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;)); shared.queued </span>= createObject(REDIS_STRING,sdsnew(<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;+QUEUED\r\n</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;)); shared.emptyscan </span>= createObject(REDIS_STRING,sdsnew(<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;*2\r\n$1\r\n0\r\n*0\r\n</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;)); shared.wrongtypeerr </span>=<span style="color: #000000;"&gt; createObject(REDIS_STRING,sdsnew( </span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;-WRONGTYPE Operation against a key holding the wrong kind of value\r\n</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;)); shared.nokeyerr </span>=<span style="color: #000000;"&gt; createObject(REDIS_STRING,sdsnew( </span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;-ERR no such key\r\n</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;)); shared.syntaxerr </span>=<span style="color: #000000;"&gt; createObject(REDIS_STRING,sdsnew( </span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;-ERR syntax error\r\n</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;)); shared.sameobjecterr </span>=<span style="color: #000000;"&gt; createObject(REDIS_STRING,sdsnew( </span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;-ERR source and destination objects are the same\r\n</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;)); shared.outofrangeerr </span>=<span style="color: #000000;"&gt; createObject(REDIS_STRING,sdsnew( </span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;-ERR index out of range\r\n</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;)); shared.noscripterr </span>=<span style="color: #000000;"&gt; createObject(REDIS_STRING,sdsnew( </span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;-NOSCRIPT No matching script. Please use EVAL.\r\n</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;)); shared.loadingerr </span>=<span style="color: #000000;"&gt; createObject(REDIS_STRING,sdsnew( </span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;-LOADING Redis is loading the dataset in memory\r\n</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;)); shared.slowscripterr </span>=<span style="color: #000000;"&gt; createObject(REDIS_STRING,sdsnew( </span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;-BUSY Redis is busy running a script. You can only call SCRIPT KILL or SHUTDOWN NOSAVE.\r\n</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;)); shared.masterdownerr </span>=<span style="color: #000000;"&gt; createObject(REDIS_STRING,sdsnew( </span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;-MASTERDOWN Link with MASTER is down and slave-serve-stale-data is set to 'no'.\r\n</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;)); shared.bgsaveerr </span>=<span style="color: #000000;"&gt; createObject(REDIS_STRING,sdsnew( </span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;-MISCONF Redis is configured to save RDB snapshots,but is currently not able to persist on disk. Commands that may modify the data set are disabled. Please check Redis logs for details about the error.\r\n</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;)); shared.roslaveerr </span>=<span style="color: #000000;"&gt; createObject(REDIS_STRING,sdsnew( </span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;-READONLY You can't write against a read only slave.\r\n</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;)); shared.noautherr </span>=<span style="color: #000000;"&gt; createObject(REDIS_STRING,sdsnew( </span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;-NOAUTH Authentication required.\r\n</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;)); shared.oomerr </span>=<span style="color: #000000;"&gt; createObject(REDIS_STRING,sdsnew( </span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;-OOM command not allowed when used memory > 'maxmemory'.\r\n</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;)); shared.execaborterr </span>=<span style="color: #000000;"&gt; createObject(REDIS_STRING,sdsnew( </span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;-EXECABORT Transaction discarded because of previous errors.\r\n</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;)); shared.noreplicaserr </span>=<span style="color: #000000;"&gt; createObject(REDIS_STRING,sdsnew( </span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;-NOREPLICAS Not enough good slaves to write.\r\n</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;)); shared.space </span>= createObject(REDIS_STRING,sdsnew(<span style="color: #800000;"&gt;"</span> <span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;)); shared.colon </span>= createObject(REDIS_STRING,sdsnew(<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;:</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;)); shared.plus </span>= createObject(REDIS_STRING,sdsnew(<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;+</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;)); </span><span style="color: #0000ff;"&gt;for</span> (j = <span style="color: #800080;"&gt;0</span>; j < REDIS_SHARED_SELECT_CMDS; j++<span style="color: #000000;"&gt;) { </span><span style="color: #0000ff;"&gt;char</span> dictid_str[<span style="color: #800080;"&gt;64</span><span style="color: #000000;"&gt;]; </span><span style="color: #0000ff;"&gt;int</span><span style="color: #000000;"&gt; dictid_len; dictid_len </span>= ll2string(dictid_str,<span style="color: #0000ff;"&gt;sizeof</span><span style="color: #000000;"&gt;(dictid_str),j); shared.</span><span style="color: #0000ff;"&gt;select</span>[j] =<span style="color: #000000;"&gt; createObject(REDIS_STRING,sdscatprintf(sdsempty(),</span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;*2\r\n$6\r\nSELECT\r\n$%d\r\n%s\r\n</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;,dictid_len,dictid_str)); } shared.messagebulk </span>= createStringObject(<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;$7\r\nmessage\r\n</span><span style="color: #800000;"&gt;"</span>,<span style="color: #800080;"&gt;13</span><span style="color: #000000;"&gt;); shared.pmessagebulk </span>= createStringObject(<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;$8\r\npmessage\r\n</span><span style="color: #800000;"&gt;"</span>,<span style="color: #800080;"&gt;14</span><span style="color: #000000;"&gt;); shared.subscribebulk </span>= createStringObject(<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;$9\r\nsubscribe\r\n</span><span style="color: #800000;"&gt;"</span>,<span style="color: #800080;"&gt;15</span><span style="color: #000000;"&gt;); shared.unsubscribebulk </span>= createStringObject(<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;$11\r\nunsubscribe\r\n</span><span style="color: #800000;"&gt;"</span>,<span style="color: #800080;"&gt;18</span><span style="color: #000000;"&gt;); shared.psubscribebulk </span>= createStringObject(<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;$10\r\npsubscribe\r\n</span><span style="color: #800000;"&gt;"</span>,<span style="color: #800080;"&gt;17</span><span style="color: #000000;"&gt;); shared.punsubscribebulk </span>= createStringObject(<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;$12\r\npunsubscribe\r\n</span><span style="color: #800000;"&gt;"</span>,<span style="color: #800080;"&gt;19</span><span style="color: #000000;"&gt;); shared.del </span>= createStringObject(<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;DEL</span><span style="color: #800000;"&gt;"</span>,<span style="color: #800080;"&gt;3</span><span style="color: #000000;"&gt;); shared.rpop </span>= createStringObject(<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;RPOP</span><span style="color: #800000;"&gt;"</span>,<span style="color: #800080;"&gt;4</span><span style="color: #000000;"&gt;); shared.lpop </span>= createStringObject(<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;LPOP</span><span style="color: #800000;"&gt;"</span>,<span style="color: #800080;"&gt;4</span><span style="color: #000000;"&gt;); shared.lpush </span>= createStringObject(<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;LPUSH</span><span style="color: #800000;"&gt;"</span>,<span style="color: #800080;"&gt;5</span><span style="color: #000000;"&gt;); </span><span style="color: #0000ff;"&gt;for</span> (j = <span style="color: #800080;"&gt;0</span>; j < REDIS_SHARED_INTEGERS; j++<span style="color: #000000;"&gt;) { shared.integers[j] </span>= createObject(REDIS_STRING,(<span style="color: #0000ff;"&gt;void</span>*)(<span style="color: #0000ff;"&gt;long</span><span style="color: #000000;"&gt;)j); shared.integers[j]</span>->encoding =<span style="color: #000000;"&gt; REDIS_ENCODING_INT; } </span><span style="color: #0000ff;"&gt;for</span> (j = <span style="color: #800080;"&gt;0</span>; j < REDIS_SHARED_BULKHDR_LEN; j++<span style="color: #000000;"&gt;) { shared.mbulkhdr[j] </span>=<span style="color: #000000;"&gt; createObject(REDIS_STRING,</span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;*%d\r\n</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;,j)); shared.bulkhdr[j] </span>=<span style="color: #000000;"&gt; createObject(REDIS_STRING,</span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;$%d\r\n</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;,j)); }

}

1.3 改变打开的最大文件数量

adjustOpenFilesLimit(= server.maxclients+</span><span style="color: #0000ff;"&gt;if</span> (getrlimit(RLIMIT_NOFILE,&amp;limit) == -<span style="color: #800080;"&gt;1</span><span style="color: #000000;"&gt;) { redisLog(REDIS_WARNING,</span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;Unable to obtain the current NOFILE limit (%s),assuming 1024 and setting the max clients configuration accordingly.</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;,strerror(errno)); server.maxclients </span>= <span style="color: #800080;"&gt;1024</span>-<span style="color: #800080;"&gt;32</span><span style="color: #000000;"&gt;; } </span><span style="color: #0000ff;"&gt;else</span><span style="color: #000000;"&gt; { rlim_t oldlimit </span>=<span style="color: #000000;"&gt; limit.rlim_cur; </span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; Set the max number of files if the current limit is not enough * for our needs. </span><span style="color: #008000;"&gt;*/</span> <span style="color: #0000ff;"&gt;if</span> (oldlimit <<span style="color: #000000;"&gt; maxfiles) { rlim_t f; f </span>=<span style="color: #000000;"&gt; maxfiles; </span><span style="color: #0000ff;"&gt;while</span>(f ><span style="color: #000000;"&gt; oldlimit) { limit.rlim_cur </span>=<span style="color: #000000;"&gt; f; limit.rlim_max </span>=<span style="color: #000000;"&gt; f; </span><span style="color: #0000ff;"&gt;if</span> (setrlimit(RLIMIT_NOFILE,&amp;limit) != -<span style="color: #800080;"&gt;1</span>) <span style="color: #0000ff;"&gt;break</span><span style="color: #000000;"&gt;; f </span>-= <span style="color: #800080;"&gt;128</span><span style="color: #000000;"&gt;; } </span><span style="color: #0000ff;"&gt;if</span> (f < oldlimit) f =<span style="color: #000000;"&gt; oldlimit; </span><span style="color: #0000ff;"&gt;if</span> (f !=<span style="color: #000000;"&gt; maxfiles) { server.maxclients </span>= f-<span style="color: #800080;"&gt;32</span><span style="color: #000000;"&gt;; redisLog(REDIS_WARNING,</span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;Unable to set the max number of files limit to %d (%s),setting the max clients configuration to %d.</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;,(</span><span style="color: #0000ff;"&gt;int</span>) maxfiles,strerror(errno),(<span style="color: #0000ff;"&gt;int</span><span style="color: #000000;"&gt;) server.maxclients); } </span><span style="color: #0000ff;"&gt;else</span><span style="color: #000000;"&gt; { redisLog(REDIS_NOTICE,</span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;Max number of open files set to %d</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;,(</span><span style="color: #0000ff;"&gt;int</span><span style="color: #000000;"&gt;) maxfiles); } } }

}

1.4 创建事件处理

aeEventLoop *aeCreateEventLoop(*</span><span style="color: #0000ff;"&gt;if</span> ((eventLoop = zmalloc(<span style="color: #0000ff;"&gt;sizeof</span>(*eventLoop))) == NULL) <span style="color: #0000ff;"&gt;goto</span><span style="color: #000000;"&gt; err; eventLoop</span>->events = zmalloc(<span style="color: #0000ff;"&gt;sizeof</span>(aeFileEvent)*<span style="color: #000000;"&gt;setsize); eventLoop</span>->fired = zmalloc(<span style="color: #0000ff;"&gt;sizeof</span>(aeFiredEvent)*<span style="color: #000000;"&gt;setsize); </span><span style="color: #0000ff;"&gt;if</span> (eventLoop->events == NULL || eventLoop->fired == NULL) <span style="color: #0000ff;"&gt;goto</span><span style="color: #000000;"&gt; err; eventLoop</span>->setsize =<span style="color: #000000;"&gt; setsize; eventLoop</span>->lastTime =<span style="color: #000000;"&gt; time(NULL); eventLoop</span>->timeEventHead =<span style="color: #000000;"&gt; NULL; eventLoop</span>->timeEventNextId = <span style="color: #800080;"&gt;0</span><span style="color: #000000;"&gt;; eventLoop</span>->stop = <span style="color: #800080;"&gt;0</span><span style="color: #000000;"&gt;; eventLoop</span>->maxfd = -<span style="color: #800080;"&gt;1</span><span style="color: #000000;"&gt;; eventLoop</span>->beforesleep =<span style="color: #000000;"&gt; NULL; </span><span style="color: #0000ff;"&gt;if</span> (aeApiCreate(eventLoop) == -<span style="color: #800080;"&gt;1</span>) <span style="color: #0000ff;"&gt;goto</span><span style="color: #000000;"&gt; err; </span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; Events with mask == AE_NONE are not set. So let's initialize the * vector with it. </span><span style="color: #008000;"&gt;*/</span> <span style="color: #0000ff;"&gt;for</span> (i = <span style="color: #800080;"&gt;0</span>; i < setsize; i++<span style="color: #000000;"&gt;) eventLoop</span>->events[i].mask =<span style="color: #000000;"&gt; AE_NONE; </span><span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; eventLoop;

err:
<span style="color: #0000ff;">if<span style="color: #000000;"> (eventLoop) {
zfree(eventLoop-><span style="color: #000000;">events);
zfree(eventLoop-><span style="color: #000000;">fired);
zfree(eventLoop);
}
<span style="color: #0000ff;">return<span style="color: #000000;"> NULL;
}

1.5 绑定监听端口

listenToPort( port, *fds, *</span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; Force binding of 0.0.0.0 if no bind address is specified,always * entering the loop if j == 0. </span><span style="color: #008000;"&gt;*/</span> <span style="color: #0000ff;"&gt;if</span> (server.bindaddr_count == <span style="color: #800080;"&gt;0</span>) server.bindaddr[<span style="color: #800080;"&gt;0</span>] =<span style="color: #000000;"&gt; NULL; </span><span style="color: #0000ff;"&gt;for</span> (j = <span style="color: #800080;"&gt;0</span>; j < server.bindaddr_count || j == <span style="color: #800080;"&gt;0</span>; j++<span style="color: #000000;"&gt;) { </span><span style="color: #0000ff;"&gt;if</span> (server.bindaddr[j] ==<span style="color: #000000;"&gt; NULL) { </span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; Bind * for both IPv6 and IPv4,we enter here only if * server.bindaddr_count == 0. </span><span style="color: #008000;"&gt;*/</span><span style="color: #000000;"&gt; fds[</span>*count] =<span style="color: #000000;"&gt; anetTcp6Server(server.neterr,port,NULL); </span><span style="color: #0000ff;"&gt;if</span> (fds[*count] != ANET_ERR) (*count)++<span style="color: #000000;"&gt;; fds[</span>*count] =<span style="color: #000000;"&gt; anetTcpServer(server.neterr,NULL); </span><span style="color: #0000ff;"&gt;if</span> (fds[*count] != ANET_ERR) (*count)++<span style="color: #000000;"&gt;; </span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; Exit the loop if we were able to bind * on IPv4 or IPv6,* otherwise fds[*count] will be ANET_ERR and we'll print an * error and return to the caller with an error. </span><span style="color: #008000;"&gt;*/</span> <span style="color: #0000ff;"&gt;if</span> (*count) <span style="color: #0000ff;"&gt;break</span><span style="color: #000000;"&gt;; } </span><span style="color: #0000ff;"&gt;else</span> <span style="color: #0000ff;"&gt;if</span> (strchr(server.bindaddr[j],<span style="color: #800000;"&gt;'</span><span style="color: #800000;"&gt;:</span><span style="color: #800000;"&gt;'</span><span style="color: #000000;"&gt;)) { </span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; Bind IPv6 address. </span><span style="color: #008000;"&gt;*/</span><span style="color: #ff0000;"&gt; fds[*count] =</span><span style="color: #000000;"&gt;<span style="color: #ff0000;"&gt; anetTcp6Server(server.neterr,server.bindaddr[j]);</span> } </span><span style="color: #0000ff;"&gt;else</span><span style="color: #000000;"&gt; { </span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; Bind IPv4 address. </span><span style="color: #008000;"&gt;*/</span><span style="color: #ff0000;"&gt; fds[*count] =</span><span style="color: #000000;"&gt;<span style="color: #ff0000;"&gt; anetTcpServer(server.neterr,server.bindaddr[j]);</span> } </span><span style="color: #0000ff;"&gt;if</span> (fds[*count] ==<span style="color: #000000;"&gt; ANET_ERR) { redisLog(REDIS_WARNING,</span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;Creating Server TCP listening socket %s:%d: %s</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;,server.bindaddr[j] </span>? server.bindaddr[j] : <span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;*</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;,server.port,server.neterr); </span><span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; REDIS_ERR; } (</span>*count)++<span style="color: #000000;"&gt;; } </span><span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; REDIS_OK;

}

1.6 创建redis数据库,并初始化一些中间状态

1.7 创建服务器时间事件

-----------------------------------------------------------------------------
<span style="color: #0000ff;">long
<span style="color: #0000ff;">long
aeCreateTimeEvent(aeEventLoop eventLoop,<span style="color: #0000ff;">long
<span style="color: #0000ff;">long
<span style="color: #000000;"> milliseconds,aeTimeProc
proc,<span style="color: #0000ff;">void
<span style="color: #000000;">clientData,aeEventFinalizerProc
<span style="color: #000000;">finalizerProc)
{
<span style="color: #0000ff;">long <span style="color: #0000ff;">long id = eventLoop->timeEventNextId++<span style="color: #000000;">;
aeTimeEvent *<span style="color: #000000;">te;

te </span>= zmalloc(<span style="color: #0000ff;"&gt;sizeof</span>(*<span style="color: #000000;"&gt;te));
</span><span style="color: #0000ff;"&gt;if</span> (te == NULL) <span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; AE_ERR;
te</span>->id =<span style="color: #000000;"&gt; id;
aeAddMillisecondsToNow(milliseconds,</span>&amp;te->when_sec,&amp;te-><span style="color: #000000;"&gt;when_ms);
te</span>->timeProc =<span style="color: #000000;"&gt; proc;
te</span>->finalizerProc =<span style="color: #000000;"&gt; finalizerProc;
te</span>->clientData =<span style="color: #000000;"&gt; clientData;
te</span>->next = eventLoop-><span style="color: #000000;"&gt;timeEventHead;
eventLoop</span>->timeEventHead =<span style="color: #000000;"&gt; te;
</span><span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; id;

}

补充:servercron

<span style="color: #0000ff;">int serverCron(<span style="color: #0000ff;">struct aeEventLoop eventLoop,<span style="color: #0000ff;">long <span style="color: #0000ff;">long id,<span style="color: #0000ff;">void <span style="color: #000000;">clientData) {
<span style="color: #0000ff;">int<span style="color: #000000;"> j;
REDIS_NOTUSED(eventLoop);
REDIS_NOTUSED(id);
REDIS_NOTUSED(clientData);

</span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; Software watchdog: deliver the SIGALRM that will reach the signal
 * handler if we don't return here fast enough. </span><span style="color: #008000;"&gt;*/</span>
<span style="color: #0000ff;"&gt;if</span><span style="color: #000000;"&gt; (server.watchdog_period) watchdogScheduleSignal(server.watchdog_period);

</span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; We take a cached value of the unix time in the global state because
 * with virtual memory and aging there is to store the current time
 * in objects at every object access,and accuracy is not needed.
 * To access a global var is faster than calling time(NULL) </span><span style="color: #008000;"&gt;*/</span><span style="color: #000000;"&gt;
server.unixtime </span>=<span style="color: #000000;"&gt; time(NULL);
server.mstime </span>=<span style="color: #000000;"&gt; mstime();

run_with_period(</span><span style="color: #800080;"&gt;100</span><span style="color: #000000;"&gt;) trackOperationsPerSecond();

</span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; We have just 22 bits per object for LRU information.
 * So we use an (eventually wrapping) LRU clock with 10 seconds resolution.
 * 2^22 bits with 10 seconds resolution is more or less 1.5 years.
 *
 * Note that even if this will wrap after 1.5 years it's not a problem,* everything will still work but just some object will appear younger
 * to Redis. But for this to happen a given object should never be touched
 * for 1.5 years.
 *
 * Note that you can change the resolution altering the
 * REDIS_LRU_CLOCK_RESOLUTION define.
 </span><span style="color: #008000;"&gt;*/</span><span style="color: #000000;"&gt;
updateLRUClock();

</span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; Record the max memory used since the server was started. </span><span style="color: #008000;"&gt;*/</span>
<span style="color: #0000ff;"&gt;if</span> (zmalloc_used_memory() ><span style="color: #000000;"&gt; server.stat_peak_memory)
    server.stat_peak_memory </span>=<span style="color: #000000;"&gt; zmalloc_used_memory();

</span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; We received a SIGTERM,shutting down here in a safe way,as it is
 * not ok doing so inside the signal handler. </span><span style="color: #008000;"&gt;*/</span>
<span style="color: #0000ff;"&gt;if</span><span style="color: #000000;"&gt; (server.shutdown_asap) {
    </span><span style="color: #0000ff;"&gt;if</span> (prepareForShutdown(<span style="color: #800080;"&gt;0</span>) == REDIS_OK) exit(<span style="color: #800080;"&gt;0</span><span style="color: #000000;"&gt;);
    redisLog(REDIS_WARNING,</span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;SIGTERM received but errors trying to shut down the server,check the logs for more information</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;);
    server.shutdown_asap </span>= <span style="color: #800080;"&gt;0</span><span style="color: #000000;"&gt;;
}

</span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; Show some info about non-empty databases </span><span style="color: #008000;"&gt;*/</span><span style="color: #000000;"&gt;
run_with_period(</span><span style="color: #800080;"&gt;5000</span><span style="color: #000000;"&gt;) {
    </span><span style="color: #0000ff;"&gt;for</span> (j = <span style="color: #800080;"&gt;0</span>; j < server.dbnum; j++<span style="color: #000000;"&gt;) {
        </span><span style="color: #0000ff;"&gt;long</span> <span style="color: #0000ff;"&gt;long</span><span style="color: #000000;"&gt; size,used,vkeys;

        size </span>=<span style="color: #000000;"&gt; dictSlots(server.db[j].dict);
        used </span>=<span style="color: #000000;"&gt; dictSize(server.db[j].dict);
        vkeys </span>=<span style="color: #000000;"&gt; dictSize(server.db[j].expires);
        </span><span style="color: #0000ff;"&gt;if</span> (used ||<span style="color: #000000;"&gt; vkeys) {
            redisLog(REDIS_VERBOSE,</span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;DB %d: %lld keys (%lld volatile) in %lld slots HT.</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;,j,vkeys,size);
            </span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; dictPrintStats(server.dict); </span><span style="color: #008000;"&gt;*/</span><span style="color: #000000;"&gt;
        }
    }
}

</span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; Show information about connected clients </span><span style="color: #008000;"&gt;*/</span>
<span style="color: #0000ff;"&gt;if</span> (!<span style="color: #000000;"&gt;server.sentinel_mode) {
    run_with_period(</span><span style="color: #800080;"&gt;5000</span><span style="color: #000000;"&gt;) {
        redisLog(REDIS_VERBOSE,</span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;%lu clients connected (%lu slaves),%zu bytes in use</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;,listLength(server.clients)</span>-<span style="color: #000000;"&gt;listLength(server.slaves),listLength(server.slaves),zmalloc_used_memory());
    }
}

</span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; We need to do a few operations on clients asynchronously. </span><span style="color: #008000;"&gt;*/</span><span style="color: #000000;"&gt;
clientsCron();

</span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; Handle background operations on Redis databases. </span><span style="color: #008000;"&gt;*/</span><span style="color: #000000;"&gt;
databasesCron();

</span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; Start a scheduled AOF rewrite if this was requested by the user while
 * a BGSAVE was in progress. </span><span style="color: #008000;"&gt;*/</span>
<span style="color: #0000ff;"&gt;if</span> (server.rdb_child_pid == -<span style="color: #800080;"&gt;1</span> &amp;&amp; server.aof_child_pid == -<span style="color: #800080;"&gt;1</span> &amp;&amp;<span style="color: #000000;"&gt;
    server.aof_rewrite_scheduled)
{
    rewriteAppendOnlyFileBackground();
}

</span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; Check if a background saving or AOF rewrite in progress terminated. </span><span style="color: #008000;"&gt;*/</span>
<span style="color: #0000ff;"&gt;if</span> (server.rdb_child_pid != -<span style="color: #800080;"&gt;1</span> || server.aof_child_pid != -<span style="color: #800080;"&gt;1</span><span style="color: #000000;"&gt;) {
    </span><span style="color: #0000ff;"&gt;int</span><span style="color: #000000;"&gt; statloc;
    pid_t pid;

    </span><span style="color: #0000ff;"&gt;if</span> ((pid = wait3(&amp;statloc,WNOHANG,NULL)) != <span style="color: #800080;"&gt;0</span><span style="color: #000000;"&gt;) {
        </span><span style="color: #0000ff;"&gt;int</span> exitcode =<span style="color: #000000;"&gt; WEXITSTATUS(statloc);
        </span><span style="color: #0000ff;"&gt;int</span> bysignal = <span style="color: #800080;"&gt;0</span><span style="color: #000000;"&gt;;

        </span><span style="color: #0000ff;"&gt;if</span> (WIFSIGNALED(statloc)) bysignal =<span style="color: #000000;"&gt; WTERMSIG(statloc);

        </span><span style="color: #0000ff;"&gt;if</span> (pid ==<span style="color: #000000;"&gt; server.rdb_child_pid) {
            backgroundSaveDoneHandler(exitcode,bysignal);
        } </span><span style="color: #0000ff;"&gt;else</span> <span style="color: #0000ff;"&gt;if</span> (pid ==<span style="color: #000000;"&gt; server.aof_child_pid) {
            backgroundRewriteDoneHandler(exitcode,bysignal);
        } </span><span style="color: #0000ff;"&gt;else</span><span style="color: #000000;"&gt; {
            redisLog(REDIS_WARNING,</span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;Warning,detected child with unmatched pid: %ld</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;,(</span><span style="color: #0000ff;"&gt;long</span><span style="color: #000000;"&gt;)pid);
        }
        updateDictResizePolicy();
    }
} </span><span style="color: #0000ff;"&gt;else</span><span style="color: #000000;"&gt; {
    </span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; If there is not a background saving/rewrite in progress check if
     * we have to save/rewrite now </span><span style="color: #008000;"&gt;*/</span>
     <span style="color: #0000ff;"&gt;for</span> (j = <span style="color: #800080;"&gt;0</span>; j < server.saveparamslen; j++<span style="color: #000000;"&gt;) {
        </span><span style="color: #0000ff;"&gt;struct</span> saveparam *sp = server.saveparams+<span style="color: #000000;"&gt;j;

        </span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; Save if we reached the given amount of changes,* the given amount of seconds,and if the latest bgsave was
         * successful or if,in case of an error,at least
         * REDIS_BGSAVE_RETRY_DELAY seconds already elapsed. </span><span style="color: #008000;"&gt;*/</span>
        <span style="color: #0000ff;"&gt;if</span> (server.dirty >= sp->changes &amp;&amp;<span style="color: #000000;"&gt;
            server.unixtime</span>-server.lastsave > sp->seconds &amp;&amp;<span style="color: #000000;"&gt;
            (server.unixtime</span>-server.lastbgsave_try ><span style="color: #000000;"&gt;
             REDIS_BGSAVE_RETRY_DELAY </span>||<span style="color: #000000;"&gt;
             server.lastbgsave_status </span>==<span style="color: #000000;"&gt; REDIS_OK))
        {
            redisLog(REDIS_NOTICE,</span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;%d changes in %d seconds. Saving...</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;,sp</span>->changes,(<span style="color: #0000ff;"&gt;int</span>)sp-><span style="color: #000000;"&gt;seconds);
            rdbSaveBackground(server.rdb_filename);
            </span><span style="color: #0000ff;"&gt;break</span><span style="color: #000000;"&gt;;
        }
     }

     </span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; Trigger an AOF rewrite if needed </span><span style="color: #008000;"&gt;*/</span>
     <span style="color: #0000ff;"&gt;if</span> (server.rdb_child_pid == -<span style="color: #800080;"&gt;1</span> &amp;&amp;<span style="color: #000000;"&gt;
         server.aof_child_pid </span>== -<span style="color: #800080;"&gt;1</span> &amp;&amp;<span style="color: #000000;"&gt;
         server.aof_rewrite_perc </span>&amp;&amp;<span style="color: #000000;"&gt;
         server.aof_current_size </span>><span style="color: #000000;"&gt; server.aof_rewrite_min_size)
     {
        </span><span style="color: #0000ff;"&gt;long</span> <span style="color: #0000ff;"&gt;long</span> <span style="color: #0000ff;"&gt;base</span> = server.aof_rewrite_base_size ?<span style="color: #000000;"&gt;
                        server.aof_rewrite_base_size : </span><span style="color: #800080;"&gt;1</span><span style="color: #000000;"&gt;;
        </span><span style="color: #0000ff;"&gt;long</span> <span style="color: #0000ff;"&gt;long</span> growth = (server.aof_current_size*<span style="color: #800080;"&gt;100</span>/<span style="color: #0000ff;"&gt;base</span>) - <span style="color: #800080;"&gt;100</span><span style="color: #000000;"&gt;;
        </span><span style="color: #0000ff;"&gt;if</span> (growth >=<span style="color: #000000;"&gt; server.aof_rewrite_perc) {
            redisLog(REDIS_NOTICE,</span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;Starting automatic rewriting of AOF on %lld%% growth</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;,growth);
            rewriteAppendOnlyFileBackground();
        }
     }
}


</span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; If we postponed an AOF buffer flush,let's try to do it every time the
 * cron function is called. </span><span style="color: #008000;"&gt;*/</span>
<span style="color: #0000ff;"&gt;if</span> (server.aof_flush_postponed_start) flushAppendOnlyFile(<span style="color: #800080;"&gt;0</span><span style="color: #000000;"&gt;);

</span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; Close clients that need to be closed asynchronous </span><span style="color: #008000;"&gt;*/</span><span style="color: #000000;"&gt;
freeClientsInAsyncFreeQueue();

</span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; Replication cron function -- used to reconnect to master and
 * to detect transfer failures. </span><span style="color: #008000;"&gt;*/</span><span style="color: #000000;"&gt;
run_with_period(</span><span style="color: #800080;"&gt;1000</span><span style="color: #000000;"&gt;) replicationCron();

</span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; Run the sentinel timer if we are in sentinel mode. </span><span style="color: #008000;"&gt;*/</span><span style="color: #000000;"&gt;
run_with_period(</span><span style="color: #800080;"&gt;100</span><span style="color: #000000;"&gt;) {
    </span><span style="color: #0000ff;"&gt;if</span><span style="color: #000000;"&gt; (server.sentinel_mode) sentinelTimer();
}

server.cronloops</span>++<span style="color: #000000;"&gt;;
</span><span style="color: #0000ff;"&gt;return</span> <span style="color: #800080;"&gt;1000</span>/<span style="color: #000000;"&gt;server.hz;

}

1.8 创建事件处理

0 && aeCreateFileEvent(server.el,        acceptUnixHandler,NULL) == AE_ERR) redisPanic("Unrecoverable error creating server.sofd file event.");

1.9 打开aof文件

(server.aof_state ===

1.10 限制32位机器内存,防止crashed

= 3072LL*(*); =

1.11 复制初始化

<span style="color: #008000;">/<span style="color: #008000;"> Initialize the script cache,only called at startup. <span style="color: #008000;">/
<span style="color: #0000ff;">void replicationScriptCacheInit(<span style="color: #0000ff;">void<span style="color: #000000;">) {
server.repl_scriptcache_size = <span style="color: #800080;">10000<span style="color: #000000;">;
server.repl_scriptcache_dict = dictCreate(&<span style="color: #000000;">replScriptCacheDictType,NULL);
server.repl_scriptcache_fifo =<span style="color: #000000;"> listCreate();
}

1.12 初始化lua脚本环境

scriptingInit(*lua =luaLoadLibraries(lua); luaRemoveUnsupportedFunctions(lua); </span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; Initialize a dictionary we use to map SHAs to scripts. * This is useful for replication,as we need to replicate EVALSHA * as EVAL,so we need to remember the associated script. </span><span style="color: #008000;"&gt;*/</span><span style="color: #000000;"&gt; server.lua_scripts </span>= dictCreate(&amp;<span style="color: #000000;"&gt;shaScriptObjectDictType,NULL); </span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; Register the redis commands table and fields </span><span style="color: #008000;"&gt;*/</span><span style="color: #000000;"&gt; lua_newtable(lua); </span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; redis.call </span><span style="color: #008000;"&gt;*/</span><span style="color: #000000;"&gt; lua_pushstring(lua,</span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;call</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;); lua_pushcfunction(lua,luaRedisCallCommand); lua_settable(lua,</span>-<span style="color: #800080;"&gt;3</span><span style="color: #000000;"&gt;); </span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; redis.pcall </span><span style="color: #008000;"&gt;*/</span><span style="color: #000000;"&gt; lua_pushstring(lua,</span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;pcall</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;); lua_pushcfunction(lua,luaRedisPCallCommand); lua_settable(lua,</span>-<span style="color: #800080;"&gt;3</span><span style="color: #000000;"&gt;); </span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; redis.log and log levels. </span><span style="color: #008000;"&gt;*/</span><span style="color: #000000;"&gt; lua_pushstring(lua,</span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;log</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;); lua_pushcfunction(lua,luaLogCommand); lua_settable(lua,</span>-<span style="color: #800080;"&gt;3</span><span style="color: #000000;"&gt;); lua_pushstring(lua,</span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;LOG_DEBUG</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;); lua_pushnumber(lua,REDIS_DEBUG); lua_settable(lua,</span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;LOG_VERBOSE</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;); lua_pushnumber(lua,REDIS_VERBOSE); lua_settable(lua,</span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;LOG_NOTICE</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;); lua_pushnumber(lua,REDIS_NOTICE); lua_settable(lua,</span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;LOG_WARNING</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;); lua_pushnumber(lua,REDIS_WARNING); lua_settable(lua,</span>-<span style="color: #800080;"&gt;3</span><span style="color: #000000;"&gt;); </span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; redis.sha1hex </span><span style="color: #008000;"&gt;*/</span><span style="color: #000000;"&gt; lua_pushstring(lua,</span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;sha1hex</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;); lua_pushcfunction(lua,luaRedisSha1hexCommand); lua_settable(lua,</span>-<span style="color: #800080;"&gt;3</span><span style="color: #000000;"&gt;); </span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; redis.error_reply and redis.status_reply </span><span style="color: #008000;"&gt;*/</span><span style="color: #000000;"&gt; lua_pushstring(lua,</span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;error_reply</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;); lua_pushcfunction(lua,luaRedisErrorReplyCommand); lua_settable(lua,</span>-<span style="color: #800080;"&gt;3</span><span style="color: #000000;"&gt;); lua_pushstring(lua,</span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;status_reply</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;); lua_pushcfunction(lua,luaRedisStatusReplyCommand); lua_settable(lua,</span>-<span style="color: #800080;"&gt;3</span><span style="color: #000000;"&gt;); </span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; Finally set the table as 'redis' global var. </span><span style="color: #008000;"&gt;*/</span><span style="color: #000000;"&gt; lua_setglobal(lua,</span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;redis</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;); </span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; Replace math.random and math.randomseed with our implementations. </span><span style="color: #008000;"&gt;*/</span><span style="color: #000000;"&gt; lua_getglobal(lua,</span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;math</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;); lua_pushstring(lua,</span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;random</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;); lua_pushcfunction(lua,redis_math_random); lua_settable(lua,</span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;randomseed</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;); lua_pushcfunction(lua,redis_math_randomseed); lua_settable(lua,</span>-<span style="color: #800080;"&gt;3</span><span style="color: #000000;"&gt;); lua_setglobal(lua,</span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;math</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;); </span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; Add a helper function that we use to sort the multi bulk output of non * deterministic commands,when containing 'false' elements. </span><span style="color: #008000;"&gt;*/</span><span style="color: #000000;"&gt; { </span><span style="color: #0000ff;"&gt;char</span> *compare_func = <span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;function __redis__compare_helper(a,b)\n</span><span style="color: #800000;"&gt;"</span> <span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt; if a == false then a = '' end\n</span><span style="color: #800000;"&gt;"</span> <span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt; if b == false then b = '' end\n</span><span style="color: #800000;"&gt;"</span> <span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt; return a<b\n</span><span style="color: #800000;"&gt;"</span> <span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;end\n</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;; luaL_loadbuffer(lua,compare_func,strlen(compare_func),</span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;@cmp_func_def</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;); lua_pcall(lua,<span style="color: #800080;"&gt;0</span>,<span style="color: #800080;"&gt;0</span><span style="color: #000000;"&gt;); } </span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; Add a helper function we use for pcall error reporting. * Note that when the error is in the C function we want to report the * information about the caller,that's what makes sense from the point * of view of the user debugging a script. </span><span style="color: #008000;"&gt;*/</span><span style="color: #000000;"&gt; { </span><span style="color: #0000ff;"&gt;char</span> *errh_func = <span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;function __redis__err__handler(err)\n</span><span style="color: #800000;"&gt;"</span> <span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt; local i = debug.getinfo(2,'nSl')\n</span><span style="color: #800000;"&gt;"</span> <span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt; if i and i.what == 'C' then\n</span><span style="color: #800000;"&gt;"</span> <span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt; i = debug.getinfo(3,'nSl')\n</span><span style="color: #800000;"&gt;"</span> <span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt; end\n</span><span style="color: #800000;"&gt;"</span> <span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt; if i then\n</span><span style="color: #800000;"&gt;"</span> <span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt; return i.source .. ':' .. i.currentline .. ': ' .. err\n</span><span style="color: #800000;"&gt;"</span> <span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt; else\n</span><span style="color: #800000;"&gt;"</span> <span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt; return err\n</span><span style="color: #800000;"&gt;"</span> <span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt; end\n</span><span style="color: #800000;"&gt;"</span> <span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;end\n</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;; luaL_loadbuffer(lua,errh_func,strlen(errh_func),</span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;@err_handler_def</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;); lua_pcall(lua,<span style="color: #800080;"&gt;0</span><span style="color: #000000;"&gt;); } </span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; Create the (non connected) client that we use to execute Redis commands * inside the Lua interpreter. * Note: there is no need to create it again when this function is called * by scriptingReset(). </span><span style="color: #008000;"&gt;*/</span> <span style="color: #0000ff;"&gt;if</span> (server.lua_client ==<span style="color: #000000;"&gt; NULL) { server.lua_client </span>= createClient(-<span style="color: #800080;"&gt;1</span><span style="color: #000000;"&gt;); server.lua_client</span>->flags |=<span style="color: #000000;"&gt; REDIS_LUA_CLIENT; } </span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; Lua beginners ofter don't use "local",this is likely to introduce * subtle bugs in their code. To prevent problems we protect accesses * to global variables. </span><span style="color: #008000;"&gt;*/</span><span style="color: #000000;"&gt; scriptingEnableGlobalsProtection(lua); server.lua </span>=<span style="color: #000000;"&gt; lua;

}

1.13 初始化慢日志

slowlogInit(==

1.14 初始化bio

bioInit(</span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; Initialization of state vars and objects </span><span style="color: #008000;"&gt;*/</span> <span style="color: #0000ff;"&gt;for</span> (j = <span style="color: #800080;"&gt;0</span>; j < REDIS_BIO_NUM_OPS; j++<span style="color: #000000;"&gt;) { pthread_mutex_init(</span>&amp;<span style="color: #000000;"&gt;bio_mutex[j],NULL); pthread_cond_init(</span>&amp;<span style="color: #000000;"&gt;bio_condvar[j],NULL); bio_jobs[j] </span>=<span style="color: #000000;"&gt; listCreate(); bio_pending[j] </span>= <span style="color: #800080;"&gt;0</span><span style="color: #000000;"&gt;; } </span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; Set the stack size as by default it may be small in some system </span><span style="color: #008000;"&gt;*/</span><span style="color: #000000;"&gt; pthread_attr_init(</span>&amp;<span style="color: #000000;"&gt;attr); pthread_attr_getstacksize(</span>&amp;attr,&amp;<span style="color: #000000;"&gt;stacksize); </span><span style="color: #0000ff;"&gt;if</span> (!stacksize) stacksize = <span style="color: #800080;"&gt;1</span>; <span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; The world is full of Solaris Fixes </span><span style="color: #008000;"&gt;*/</span> <span style="color: #0000ff;"&gt;while</span> (stacksize < REDIS_THREAD_STACK_SIZE) stacksize *= <span style="color: #800080;"&gt;2</span><span style="color: #000000;"&gt;; pthread_attr_setstacksize(</span>&amp;<span style="color: #000000;"&gt;attr,stacksize); </span><span style="color: #008000;"&gt;/*</span><span style="color: #008000;"&gt; Ready to spawn our threads. We use the single argument the thread * function accepts in order to pass the job ID the thread is * responsible of. </span><span style="color: #008000;"&gt;*/</span> <span style="color: #0000ff;"&gt;for</span> (j = <span style="color: #800080;"&gt;0</span>; j < REDIS_BIO_NUM_OPS; j++<span style="color: #000000;"&gt;) { </span><span style="color: #0000ff;"&gt;void</span> *arg = (<span style="color: #0000ff;"&gt;void</span>*)(unsigned <span style="color: #0000ff;"&gt;long</span><span style="color: #000000;"&gt;) j; </span><span style="color: #0000ff;"&gt;if</span> (pthread_create(&amp;thread,&amp;attr,bioProcessBackgroundJobs,arg) != <span style="color: #800080;"&gt;0</span><span style="color: #000000;"&gt;) { redisLog(REDIS_WARNING,</span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;Fatal: Can't initialize Background Jobs.</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;); exit(</span><span style="color: #800080;"&gt;1</span><span style="color: #000000;"&gt;); } bio_threads[j] </span>=<span style="color: #000000;"&gt; thread; }

}

相关文章

文章浏览阅读1.3k次。在 Redis 中,键(Keys)是非常重要的概...
文章浏览阅读3.3k次,点赞44次,收藏88次。本篇是对单节点的...
文章浏览阅读8.4k次,点赞8次,收藏18次。Spring Boot 整合R...
文章浏览阅读978次,点赞25次,收藏21次。在Centos上安装Red...
文章浏览阅读1.2k次,点赞21次,收藏22次。Docker-Compose部...
文章浏览阅读2.2k次,点赞59次,收藏38次。合理的JedisPool资...