關於redis的單執行緒與後臺執行緒的原始碼分析
阿新 • • 發佈:2019-01-22
前言:
通常大家都會說redis是單執行緒的,這個理解其實也沒錯。
redis的命令處理基本上都是單執行緒處理的,除了個別任務會fork子程序進行處理。
分析版本:redis 3.0.7
其實redis是個多執行緒程序,如下圖:
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; } }
End;