关于redis的单线程与后台线程的源码分析


前言:

通常大家都会说redis是单线程的,这个理解其实也没错。

redis的命令处理基本上都是单线程处理的,除了个别任务会fork子进程进行处理。


分析版本:redis 3.0.7


其实redis是个多线程进程,如下图:

关于redis的单线程与后台线程的源码分析_第1张图片


redis的另外两个线程的作用是什么?

另外两个线程用于一些异步操作,通过条件变量控制任务,主要用于close(2),fsync(2)的操作,

因为close(2)一个文件句柄时,如果程序是文件的最后一个拥有者,那么代表着要unlink它,相对来说会很慢,产生阻塞。


源码在哪里?

src/bio.h

src/bio.c

/* Initialize the background system, spawning the thread. */
void bioInit(void) {
    pthread_attr_t attr;
    pthread_t thread;
    size_t stacksize;
    int j;

    /* Initialization of state vars and objects */
    for (j = 0; j < REDIS_BIO_NUM_OPS; j++) {
        pthread_mutex_init(&bio_mutex[j],NULL);
        pthread_cond_init(&bio_condvar[j],NULL);
        bio_jobs[j] = listCreate();
        bio_pending[j] = 0;
    }

    /* Set the stack size as by default it may be small in some system */
    pthread_attr_init(&attr);
    pthread_attr_getstacksize(&attr,&stacksize);
    if (!stacksize) stacksize = 1; /* The world is full of Solaris Fixes */
    while (stacksize < REDIS_THREAD_STACK_SIZE) stacksize *= 2;
    pthread_attr_setstacksize(&attr, stacksize);

    /* 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. */
    for (j = 0; j < REDIS_BIO_NUM_OPS; j++) {
        void *arg = (void*)(unsigned long) j;
        if (pthread_create(&thread,&attr,bioProcessBackgroundJobs,arg) != 0) {
            redisLog(REDIS_WARNING,"Fatal: Can't initialize Background Jobs.");
            exit(1);
        }
        bio_threads[j] = thread;
    }
}


原文出自:http://blog.csdn.net/daiyudong2020/article/details/53907415



End;





你可能感兴趣的:(redis,Redis)