从源码看redis多线程模型

157 阅读1分钟

启用多线程

io-threads num

设置io线程进行额外的读取操作

io-threads-do-reads yes

主线程+io线程

主线程接受链接,添加client到io线程的列表中, 在sleep前,如果开启io线程处理读,那么设置设置io操作为读,否则自己处理读,处理完其他一些任务后设置io操作为写 io线程循环检查到io操作为读,那么处理读,如果检查到io操作为写,则处理写

处理命令由主线程操作

相关源码 server.c中

int main(int argc, char **argv) {
...
InitServerLast()
...
}

server.c中

void InitServerLast() {
    bioInit();
    initThreadedIO();
    set_jemalloc_bg_thread(server.jemalloc_bg_thread);
    server.initial_memory_usage = zmalloc_used_memory();
}

networking.c中

void initThreadedIO(void) {
...
    for (int i = 0; i < server.io_threads_num; i++) {
      /* Things we do for all the threads including the main thread. */
      io_threads_list[i] = listCreate();
      if (i == 0) continue; /* Thread 0 is the main thread. */

      /* Things we do only for the additional threads. */
      pthread_t tid;
      pthread_mutex_init(&io_threads_mutex[i],NULL);
      io_threads_pending[i] = 0;
      pthread_mutex_lock(&io_threads_mutex[i]); /* Thread will be stopped. */
      if (pthread_create(&tid,NULL,IOThreadMain,(void*)(long)i) != 0) {
          serverLog(LL_WARNING,"Fatal: Can't initialize IO thread.");
          exit(1);
      }
      io_threads[i] = tid;
    }
    ...
}    

networking.c中

void *IOThreadMain(void *myid) {
  ...
  while((ln = listNext(&li))) {
      client *c = listNodeValue(ln);
      if (io_threads_op == IO_THREADS_OP_WRITE) {
          writeToClient(c,0);
      } else if (io_threads_op == IO_THREADS_OP_READ) {
          readQueryFromClient(c->conn);
      } else {
          serverPanic("io_threads_op value is unknown");
      }
  }
  ...
}