blpop阻塞问题
来源:4-4 发布订阅

Panda_io
2020-04-25
老师redis是单线程,当我使用blpop key 0 时线程出现阻塞,既然线程阻塞了,其他操作就应该不能执行了我的理解是这样,但是为何我可以重开一个客户端,把值push进去呢
我就是不明白,既然是单线程,线程阻塞了,那么肯定不能处理其他任务了呀,请老师指点一下
1回答
-
执行blpop等阻塞命令时,主要调用t_list中的void blpopCommand(redisClient *c)函数,该函数主要是调用blockingPopGenericCommand(c,REDIS_HEAD)来进行最终命令的执行
这样组可以使得brpop命令也调用该函数,只需要改变pop的方向。
如果发生了超时错误,则直接返回
否则就使用lookupKeyWrite判断键是否存在,如果键存在但是不是list类型,那么就返回一个类型错误给客户端;否则就对list进行操作,当list的长度不为0时,就从链表中弹出一个元素并返回给客户端,如果此时list长度为0,那么就调用删除程序,在aof文件中使用l[r]pop命令记录,而不是使用阻塞的命令进行计算。换句话说,如果bl[r]pop操作list时,如果list不为空,那么和l[r]pop的操作是一样的。
如果命令在事务中执行,则会返回一个空回复
如果所有的请求的键不存在,则对客户端进行阻塞。服务器不再对这个客户端发送任何数据,对这个客户端的状态设为“被阻塞“,直到解除阻塞为止。并且客户端会被加入到一个以阻塞键为 key ,以被阻塞客户端为 value 的字典 db->blocking_keys 中。
当有 PUSH 命令作用于一个造成客户端阻塞的键时, 程序将这个键标记为“就绪”,并且在执行完这个命令、事务、或脚本之后,程序会按“先阻塞先服务”的顺序,将列表的元素返回给那些被阻塞的客户端,被解除阻塞的客户端数量取决于 PUSH 命令推入的元素数量。
112020-06-24
相似问题