从redis的API可以了解到lpop,rpop可以实现一个阻塞式队列。那疑问就来了,redis不是单线程的吗,如果阻塞了,那其他操作就执行不了呀。事实不是这样的
redis的线程模型,是接收客户端命令的线程时 I/O 多路复用的,再通过文件事件分配器单线程执行的。如下图,程序总是会将所有产生事件的套接字都入队到一个队列里面, 然后通过这个队列, 以有序(sequentially)、同步(synchronously)、每次一个套接字的方式向文件事件分派器传送套接字: 当上一个套接字产生的事件被处理完毕之后(该套接字为事件所关联的事件处理器执行完毕), I/O 多路复用程序才会继续向文件事件分派器传送下一个套接字
那实际上我们关心的BLPOP 命令的执行就是在文件事件分派器分派后是怎么执行的了。
对BLPOP命令的处理流程是这样的:
redis先找到对应的key的list,如果list不为空则pop一个数据返回给客户端;
如果list为空,或者list不存在,就将该key添加到一个blockling_keys的字典中,value就是想订阅该key的client