目录

先说明下redis也是多线程的.但是redis的主线程处理业务.而其他三个线程跟主要功能是关系不到的

redis的三个线程主要是做什么

初始化入口void initServer(void) {

...

bioInit();

...

}

初始化后redis其他后台线程.void bioInit(void) {

pthread_attr_t attr;

pthread_t thread;

size_t stacksize;

int j;

/* Initialization of state vars and objects

*

* 初始化 job 队列,以及线程状态

*/

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;

}

}

初始化三类线程. 这三类线程被认为是后台执行.不影响主线程BIO_CLOSE_FILE . 关闭重写之前的aof文件.

BIO_AOF_FSYNC . 定时刷新数据到磁盘上.

BIO_LAZY_FREE . 惰性删除过期时间数据

redis为了保证其高效.一些比较耗时的动作会起线程或者进程来完成.不会阻塞在业务主线程上.

使用多线程的特点创建3个线程.这个三个线程的功能互不影响

每个线程都有一个工作队列.主线程生产任务放到任务队里.这三个线程消费这些任务.

任务队列和取出消费的时候都得加锁.防止竞争

使用条件变量来等待任务.以及通知// 存放工作的队列

static list *bio_jobs[REDIS_BIO_NUM_OPS];

bio_jobs是一个双端链表结构void bioCreateBackgroundJob(int type, void *arg1, void *arg2, void *arg3) {

struct bio_job *job = zmalloc(sizeof(*job));

job->time = time(NULL);

job->arg1 = arg1;

job->arg2 = arg2;

job->arg3 = arg3;

pthread_mutex_lock(&bio_mutex[type]);

// 将新工作推入队列

listAddNodeTail(bio_jobs[type],job);

bio_pending[type]++;

pthread_cond_signal(&bio_condvar[type]);

pthread_mutex_unlock(&bio_mutex[type]);

}

当有任务的时候.先把任务丢到redis工作队列里.这里记得加锁void *bioProcessBackgroundJobs(void *arg) {

struct bio_job *job;

unsigned long type = (unsigned long) arg;

sigset_t sigset;

/* Make the thread killable at any time, so that bioKillThreads()

* can work reliably. */

pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);

pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);

pthread_mutex_lock(&bio_mutex[type]);

/* Block SIGALRM so we are sure that only the main thread will

* receive the watchdog signal. */

sigemptyset(&sigset);

sigaddset(&sigset, SIGALRM);

if (pthread_sigmask(SIG_BLOCK, &sigset, NULL))

redisLog(REDIS_WARNING,

"Warning: can't mask SIGALRM in bio.c thread: %s", strerror(errno));

while(1) {

listNode *ln;

/* The loop always starts with the lock hold. */

if (listLength(bio_jobs[type]) == 0) {

pthread_cond_wait(&bio_condvar[type],&bio_mutex[type]);

continue;

}

/* Pop the job from the queue.

*

* 取出(但不删除)队列中的首个任务

*/

ln = listFirst(bio_jobs[type]);

job = ln->value;

/* It is now possible to unlock the background system as we know have

* a stand alone job structure to process.*/

pthread_mutex_unlock(&bio_mutex[type]);

/* Process the job accordingly to its type. */

// 执行任务

if (type == REDIS_BIO_CLOSE_FILE) {

close((long)job->arg1);

} else if (type == REDIS_BIO_AOF_FSYNC) {

aof_fsync((long)job->arg1);

} else {

redisPanic("Wrong job type in bioProcessBackgroundJobs().");

}

zfree(job);

/* Lock again before reiterating the loop, if there are no longer

* jobs to process we'll block again in pthread_cond_wait(). */

pthread_mutex_lock(&bio_mutex[type]);

// 将执行完成的任务从队列中删除,并减少任务计数器

listDelNode(bio_jobs[type],ln);

bio_pending[type]--;

}

}操作前先上锁

从工作任务里取任务

解锁

执行业务逻辑

执行完上锁.重新pthread_cond_wait

条件变量

条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待"条件变量的条件成立"而挂起;

另一个线程使"条件成立"(给出条件成立信号)。

==为了防止竞争,条件变量的使用总是和一个互斥锁结合在一起==

pthread_cond_wait原理

就是说pthread_cond_wait(pthread_cond_t cond, pthread_mutex_tmutex)函数传入的参数mutex用于保护条件,因为我们在调用pthread_cond_wait时,如果条件不成立我们就进入阻塞,但是进入阻塞这个期间,如果条件变量改变了的话,那我们就漏掉了这个条件。因为这个线程还没有放到等待队列上,所以调用pthread_cond_wait前要先锁互斥量,即调用pthread_mutex_lock()。

==pthread_cond_wait在把线程放进阻塞队列后,自动对mutex进行解锁,使得其它线程可以获得加锁的权利。这样其它线程才能对临界资源进行访问并在适当的时候唤醒这个阻塞的进程。当pthread_cond_wait返回的时候又自动给mutex加锁==

php 多线程处理redis,redis的多线程相关推荐

  1. Redis 6.0 多线程重磅发布!来了解一下吧

    Redis 6.0发布了,这次发布在IT圈犹如一颗惊雷一般,因为这是redis最大的一次改版,首次加入了多线程. 作者Antirez在RC1版本发布时在他的博客写下: the most "e ...

  2. Redis 6.0多线程模型总结

    前言:Redis 6.0.1 于 2020 年 5 月 2 日正式发布了,如 Redis 作者 antirez 所说,这是迄今为止最"企业"化的版本,也是有史以来改动最大的一个 R ...

  3. 查看linux上面是否有安装redis,redis启动

    1.检测是否有安装redis-cli和redis-server; [root@localhost bin]# whereis redis-cli redis-cli: /usr/bin/redis-c ...

  4. ServiceStack.Redis——Redis于.net向上client解

    ServiceStack.Redis--Redis于.net向上client解 源代码和使用: https://github.com/ServiceStack/ServiceStack.Redis 样 ...

  5. php 不识别redis,redis,_redis卡死无法读取数据如何解决?,redis - phpStudy

    redis卡死无法读取数据如何解决? 之前是redis dump.rdb 的时候会卡死,然后我关掉了save功能,但是过了一段时间之后又卡死了,这次不知道什么原因,怎样解决了. 以下是info的信息: ...

  6. Redis - Redis command timed out nested exception is io.lettuce.core.RedisCommandTimeoutException

    Redis - Redis command timed out nested exception is io.lettuce.core.RedisCommandTimeoutException 这个问 ...

  7. [redis] Redis 配置文件置参数详解

    ################################ 基础配置 ################################# #daemonize no 默认情况下, redis 不 ...

  8. Redis Redis Sentinel 基本使用

    Redis & Redis-sentinel 基本使用 本文主要介绍如下几点内容: Redis基本配置 Redis Sentinel基本配置 Redis Client客户端基本内容 Redis ...

  9. 跟我学Redis——Redis安装

    Redis介绍 Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库.缓存和消息中间件. 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), ...

最新文章

  1. 用python做一个图片验证码
  2. 方程组c语言编程,最小二乘解方程组C语言编程.doc
  3. python str 换行_Python学习之路(1)
  4. jzoj1252,P5194-天平【dfs,set】
  5. 面向对象方法及软件工程——团队答辩
  6. c语言简单的动画程序代码,发个C代码(简单动画演示)
  7. Linux学习笔记005----CentOS7 vi模式保存并退出
  8. struts国际化java_Struts2 的国际化实现方式示例
  9. ZBrush中Tool工具的保存
  10. ThinkPHP框架学习(一)
  11. cad2010多个文件并排显示_CAD软件同时显示两张或多张图纸的方法
  12. wap 横屏适配和竖屏适配的通用方案
  13. 驾照ABC:准驾车型及代号
  14. Vue教程(四十七)Promise基本介绍与使用
  15. Oracle GoldenGate官档知识
  16. LeetCode 860[Python]. 柠檬水找零 在柠檬水摊上,每一杯柠檬水的售价为 5 美元。 顾客排队购买你的产品,(按账单 bills 支付的顺序)一次购买一杯。
  17. android手机为什么卡?
  18. 小木虫 高光谱遥感图像处理_高光谱图像变化检测
  19. 解决手机连上电脑热点上不了网的问题
  20. android 定时截图,这款 APP 让我每天都忍不住想发截图!

热门文章

  1. Linux下nm和ldd 命令
  2. iservice封装有哪些方法_5w大功率led白光灯珠参数,5w大功率led灯珠有哪些?
  3. 多台电脑共用一个耳机、音箱
  4. 牛客网-数据结构笔试题目(二)-万万没想到之抓捕孔连顺思路解析(附源码)
  5. 哔哩哔哩swot分析_哔哩哔哩2020校园招聘游戏运营笔试真题
  6. linux 定义快捷命令,Linux系统自定义快捷命令的详细说明
  7. 如何做好内容策划并完成一篇合格的深度文?
  8. 【算法图解|2】JavaScript 如何实现数组扁平化
  9. 教你玩转CSS 居中
  10. Bash脚本教程之行操作