免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12
最近访问板块 发新帖
楼主: linux_c_py_php
打印 上一主题 下一主题

[其他] 【实测比较half-sync-half-async模式与leader-follower模式的性能与场景(直播)】 [复制链接]

论坛徽章:
44
15-16赛季CBA联赛之浙江
日期:2021-10-11 02:03:59程序设计版块每日发帖之星
日期:2016-07-02 06:20:0015-16赛季CBA联赛之新疆
日期:2016-04-25 10:55:452016科比退役纪念章
日期:2016-04-23 00:51:2315-16赛季CBA联赛之山东
日期:2016-04-17 12:00:2815-16赛季CBA联赛之福建
日期:2016-04-12 15:21:2915-16赛季CBA联赛之辽宁
日期:2016-03-24 21:38:2715-16赛季CBA联赛之福建
日期:2016-03-18 12:13:4015-16赛季CBA联赛之佛山
日期:2016-02-05 00:55:2015-16赛季CBA联赛之佛山
日期:2016-02-04 21:11:3615-16赛季CBA联赛之天津
日期:2016-11-02 00:33:1215-16赛季CBA联赛之浙江
日期:2017-01-13 01:31:49
11 [报告]
发表于 2013-02-16 20:05 |显示全部楼层
回复 57# linux_c_py_php

用什么结构体保存连接本身的信息没关系,关键是如何把这些信息汇集起来
一个不动脑子的方案可以是这样:
1. 建立一个双链表
2. 新连接建立后,将连接信息插入表尾

  1. context->next=NULL;
  2. context->prev=tail;
  3. tail->next=context;
  4. tail=context;
复制代码
3. 连接结束后,将该连接从链表中摘除,在context中记录结束的时间戳,然后传递给后台的reaper thread

  1. context->prev->next=context->next;
  2. context->next->prev=context->prev;
  3. context->prev=reaper_list_tail;
复制代码
4. reaper thread维护另外一个反向的单链表,这个链表只使用/调整prev指针,不修改next指针,reaper定期扫描这个链表,将时间戳老于一定阈值的节点回收,其它节点不变。

  1. while(1) {
  2.     context_t *p=reaper_list_tail;
  3.     context_t *prev;
  4.     while(prev=p, p=p->prev) {
  5.         if(old_enough(p)){
  6.             prev->prev=p;
  7.             reap(p);
  8.         }
  9.     }
  10. }
复制代码
5. 遍历连接时,只单向遍历,只使用next指针,这样可以保证即使某个连接在遍历期间被放入了reaper链表,它的next依然指向一个存活的context(虽然不一定是有效的)

  1. for(context_t *p=head; p; p=p->next) {
  2.     // do something with p
  3. }
复制代码
整个过程差不多就是这样。

上述代码只在ARM/X86/X86_64这些Strong Order的平台下能工作(前提是我脑子没发晕,代码没写错,这个可能性……哼哼……很小……),对于其它平台需要引入memory order,并且需要编译器不要自作聪明调整代码顺序。

论坛徽章:
44
15-16赛季CBA联赛之浙江
日期:2021-10-11 02:03:59程序设计版块每日发帖之星
日期:2016-07-02 06:20:0015-16赛季CBA联赛之新疆
日期:2016-04-25 10:55:452016科比退役纪念章
日期:2016-04-23 00:51:2315-16赛季CBA联赛之山东
日期:2016-04-17 12:00:2815-16赛季CBA联赛之福建
日期:2016-04-12 15:21:2915-16赛季CBA联赛之辽宁
日期:2016-03-24 21:38:2715-16赛季CBA联赛之福建
日期:2016-03-18 12:13:4015-16赛季CBA联赛之佛山
日期:2016-02-05 00:55:2015-16赛季CBA联赛之佛山
日期:2016-02-04 21:11:3615-16赛季CBA联赛之天津
日期:2016-11-02 00:33:1215-16赛季CBA联赛之浙江
日期:2017-01-13 01:31:49
12 [报告]
发表于 2013-02-16 20:50 |显示全部楼层
回复 60# linux_c_py_php

要是还要锁我折腾这么一圈到底是为神马?

刚才那个例子里有几点要注意
1. old_enough需要保证这个context“足够老”,这个足够就是说它一定要比一次遍历所需的时间更长,说起来比较容易,但是考虑到OS调度的不确定性,要保证这个“一定”还是有点难度的,假设你遍历一遍需要1ms,实际上old_enough可能需要设定到几秒甚至更长。
2. 创建和删除context本身可能用到了malloc/free/new/delete,绝大部分libc实现中这几个操作都用到了锁,为了进一步避免这个开销,我们需要引入自定义的memory management,比如一个lock free的slab分配器,这个的复杂度超过了这个帖子的容量……

读写锁最大的问题就是即便你只读,它也是有开销的,而且锁会导致优先级反转,明明这个线程该干活了,结果它非要等别人……
另外,还有一个问题,如果你只是在context数组上加锁,实际上你没办法保证遍历时不会碰到正在/已经被删除的连接,除非你在整个遍历期间锁定整个context数组,并且对于“所有”context的操作都加锁,漏掉一个都不行。

论坛徽章:
44
15-16赛季CBA联赛之浙江
日期:2021-10-11 02:03:59程序设计版块每日发帖之星
日期:2016-07-02 06:20:0015-16赛季CBA联赛之新疆
日期:2016-04-25 10:55:452016科比退役纪念章
日期:2016-04-23 00:51:2315-16赛季CBA联赛之山东
日期:2016-04-17 12:00:2815-16赛季CBA联赛之福建
日期:2016-04-12 15:21:2915-16赛季CBA联赛之辽宁
日期:2016-03-24 21:38:2715-16赛季CBA联赛之福建
日期:2016-03-18 12:13:4015-16赛季CBA联赛之佛山
日期:2016-02-05 00:55:2015-16赛季CBA联赛之佛山
日期:2016-02-04 21:11:3615-16赛季CBA联赛之天津
日期:2016-11-02 00:33:1215-16赛季CBA联赛之浙江
日期:2017-01-13 01:31:49
13 [报告]
发表于 2013-02-16 20:55 |显示全部楼层
本帖最后由 windoze 于 2013-02-16 21:05 编辑

回复 61# sonicling

为什么不行呢?举个栗子?

比如这个:
Lock-Free Linked Lists Using Compare-and-Swap

还有这个:
A Pragmatic Implementation of Non-Blocking Linked-Lists

还有这个:
Lock-Free Programming

论坛徽章:
44
15-16赛季CBA联赛之浙江
日期:2021-10-11 02:03:59程序设计版块每日发帖之星
日期:2016-07-02 06:20:0015-16赛季CBA联赛之新疆
日期:2016-04-25 10:55:452016科比退役纪念章
日期:2016-04-23 00:51:2315-16赛季CBA联赛之山东
日期:2016-04-17 12:00:2815-16赛季CBA联赛之福建
日期:2016-04-12 15:21:2915-16赛季CBA联赛之辽宁
日期:2016-03-24 21:38:2715-16赛季CBA联赛之福建
日期:2016-03-18 12:13:4015-16赛季CBA联赛之佛山
日期:2016-02-05 00:55:2015-16赛季CBA联赛之佛山
日期:2016-02-04 21:11:3615-16赛季CBA联赛之天津
日期:2016-11-02 00:33:1215-16赛季CBA联赛之浙江
日期:2017-01-13 01:31:49
14 [报告]
发表于 2013-02-16 22:04 |显示全部楼层
本帖最后由 windoze 于 2013-02-16 22:18 编辑

回复 64# linux_c_py_php

无锁也可以维护连接表(虽然不一定是数组)。
Lock Free Data Structure是个挺麻烦的事,但是搞好了的确在适用的场合能极大的提高效率。
参见Non-blocking algorithm,这里有不少内容,新版的Boost里也有一组Lock Free类/模板

论坛徽章:
44
15-16赛季CBA联赛之浙江
日期:2021-10-11 02:03:59程序设计版块每日发帖之星
日期:2016-07-02 06:20:0015-16赛季CBA联赛之新疆
日期:2016-04-25 10:55:452016科比退役纪念章
日期:2016-04-23 00:51:2315-16赛季CBA联赛之山东
日期:2016-04-17 12:00:2815-16赛季CBA联赛之福建
日期:2016-04-12 15:21:2915-16赛季CBA联赛之辽宁
日期:2016-03-24 21:38:2715-16赛季CBA联赛之福建
日期:2016-03-18 12:13:4015-16赛季CBA联赛之佛山
日期:2016-02-05 00:55:2015-16赛季CBA联赛之佛山
日期:2016-02-04 21:11:3615-16赛季CBA联赛之天津
日期:2016-11-02 00:33:1215-16赛季CBA联赛之浙江
日期:2017-01-13 01:31:49
15 [报告]
发表于 2013-02-17 17:49 |显示全部楼层
回复 67# sonicling

58楼的代码,给读写操作加上MB差不多就可以了,如果你的机器没有NUMA,CPU也没有那么多,不加MB其实也没问题。

至于效率不高,你说的是reaper么?那个东东在后台,隔一阵子才跑一次,慢点无所谓,前台的速度才是关键。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP