线程安全队列
从一把锁到多生产者:阻塞队列的条件变量和丢失唤醒,rte_ring 的两对下标和按顺序发布,Disruptor 的可用标记,以及队列满了该阻塞、丢弃还是覆盖。
标签
3 篇
从一把锁到多生产者:阻塞队列的条件变量和丢失唤醒,rte_ring 的两对下标和按顺序发布,Disruptor 的可用标记,以及队列满了该阻塞、丢弃还是覆盖。
行情只有一个生产者,却有好几个消费者,每个都要看到每一条,而生产者是热路径,不能等任何人。答案是广播环:每个槽位自带序号戳,读者各持私有游标,生产者写满一圈就覆盖最老的槽位,从不读读者的状态。代价转给了读者:套圈是无声的;读完再复查一次戳,只有在写者先作废戳的前提下才抓得到写了一半的槽位;追上来的读者会抢走生产者要写的那一行,全速写时每条都变贵。放进共享内存再加三条:元素里不能有任何指针,第一圈每 32 条碰一次缺页,读者重启不存游标就全丢。
无锁 SPSC 队列成立,是因为每个共享变量只有一个写者:每一边只写自己的下标,只读对方的。剩下的工作是别让这个性质被悄悄破坏:元素个数用两个下标相减而不是共享计数器,对方的下标缓存一份、只在看起来满了或空了时才刷新,日志按文本段推而不是按字符推。SPSC 只在“失败就返回”的接口下才是 wait-free,有界队列满了总得在丢弃和阻塞之间选一个。
