-
Notifications
You must be signed in to change notification settings - Fork 4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
请问服务端回response或者客户端发送request时所使用的WriteRequest链表为什么需要反转? #2762
Comments
WriteRequest链表是个单向链表,反转就是为了从tail消费吧 |
谢谢。但我不太理解的是为什么一定要反转。如果producer在tail增加新的WriteRequest,consumer在head处消费,不需要反转链表。 |
https://github.com/apache/brpc/blob/master/docs/cn/io.md 经典的双端链表队列实现是Michael&Scott的non-blocking queue,boost里有一个对应的实现boost::lock_free:queue,不过入队动作依赖CAS,CAS本身在竞争比较大的时候有自旋问题其实并发能力一般; brpc这个单端链表核心就是通过不会失败不会自旋的exchange替换CAS提升了并发能力;也因为是通过和当前队尾进行exchage动作来成为新的队尾,整体的单链指向就只能是队尾指向前序节点的逆序链表了; 不过单纯看性能,基于数组的队列一般比链表类队列整体吞吐要高一些;所以这种链表类队列主要的优势点还是在于大量队列(例如作为接入层server承接大链接数)时不用预留数组长度,内存有节省;但是大链接数一般单链接上竞争就不强了,其实哪怕mutex保护的单链其实问题都不大;而有大并发的场景,因为链接数规模可控,可能进一步上数组队列的并发能力会更好(比如直接iouring之类的);甚至大链接数场景,按链接组做聚簇之后上数组队列可能均衡意义上有时也强过链表队列; 只看MPSC并发能力的话,比较久之前做过一个简易评测
|
@oathdruid 谢谢大佬详尽的解释,这个测试涵盖的实现真全!固定qps下 boost和babylon的实现延迟表现都不错啊看起来,极限吞吐的话也是babylon的更优。 另外现在的实现看起来应该是去往_write_head进行插入: |
目前消费动作应该也是用这个exchage摘除队尾的方式来做的。正向链消费感觉会有一些比较困难的点 初步这么理了下,感觉好像不是不能做,不过实现复杂度提升不少 |
谢谢。不过只有一个消费者从head消费,除非是writ_head和write_tail重合的时候有竞争,其它的时候这个消费者就直接去从head开始拿直到nullptr之前的结点就好了?然后就把write_head直接指到这个结点。 |
看实现是类似一个一个MPSC的无锁队列。
多个producer会通过exchange保证调用顺序和WriteRequest的插入顺序是一致的。在single consumer写之前,会找到old_head和new_head之间的WriteRequest进行链表反转,然后往fd里写出这一部分数据。
一般实现是:单纯的单链表,维护一个head和一个tail指针,producer在tail插入新的WriteRequest,而consumer在head处消费。
请问这样的一般实现和目前的实现相比,目前的实现会有哪些advantage么?是否目前的实现使得插入和消费实际上是在两个互不相干的链表上从而减少了需要race的场景?
The text was updated successfully, but these errors were encountered: