免费注册 查看新帖 |

Chinaunix

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

[C++] ASIO协程彻底转变你的思维 [复制链接]

论坛徽章:
0
11 [报告]
发表于 2013-04-16 12:43 |只看该作者
yulihua49 发表于 2013-04-16 12:39
这样有什么好处呢?我用多线程+context表示状态,每次线程调用这个context时从相应的状态点运行,也可以进 ...

实际的代码?

论坛徽章:
15
射手座
日期:2014-11-29 19:22:4915-16赛季CBA联赛之青岛
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16赛季CBA联赛之四川
日期:2017-02-07 21:08:572015年亚冠纪念徽章
日期:2015-11-06 12:31:58每日论坛发贴之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-07-12 22:20:002015亚冠之浦和红钻
日期:2015-07-08 10:10:132015亚冠之大阪钢巴
日期:2015-06-29 11:21:122015亚冠之广州恒大
日期:2015-05-22 21:55:412015年亚洲杯之伊朗
日期:2015-04-10 16:28:25
12 [报告]
发表于 2013-04-16 16:22 |只看该作者
本帖最后由 yulihua49 于 2013-04-16 16:47 编辑
qinggeng 发表于 2013-04-16 12:43
实际的代码?

这个,不扣题吧?人家说单线程asio,我说多线程asio。
  1. static void *thread_work(void *param)
  2. {
  3. resource *rs=(resource *)param;
  4. int ret,fds;
  5. TCB *task;//你可以按需要定义你自己的context。
  6. port_event_t event;

  7.         rs->tid=pthread_self();
  8.         while(1) {
  9. //从就绪队列取一个任务
  10.                 pthread_mutex_lock(&rpool.mut);
  11.                 while(!(task=rdy_get())) {         //这部分先不要管
  12.                         if(rpool.flg >= tpool.rdy_num) break;
  13.                         rpool.flg++;
  14.                         ret=pthread_cond_wait(&rpool.cond,&rpool.mut); //没有任务,等待
  15.                         rpool.flg--;
  16.                 }
  17.                 pthread_mutex_unlock(&rpool.mut);
  18.                 if(!task) {
  19.                         ret = port_get(g_port_fd, &event, NULL); //每个线程等事件,solaris的port事件管理器,=epoll_wait
  20.                         if(ret < 0){
  21.                                 ShowLog(1,"%s:port_get err=%d,%s",__FUNCTION__,errno,strerror(errno));
  22.                                 sleep(30);
  23.                                 continue;
  24.                         }
  25.                         task = (TCB *)event.portev_user;//拿到context
  26.                         task->events=event.portev_events;
  27. //检查事件是否健康
  28.                         if(!task->call_back && !(event.portev_events&POLLIN)) {
  29.                                 client_del(task);
  30.                                 continue;
  31.                         }
  32.                 }
  33. //              rs->timestamp=
  34.                 task->timestamp=now_usec();
  35.                 ret=do_work(task);//处理你的context。记住,处理完毕要把你的fd重新加入g_port_fd。好进行下一阶段的工作。
  36.         }
  37.         ShowLog(1,"%s:tid=%lu canceled",__FUNCTION__,pthread_self());
  38.         mthr_showid_del(rs->tid);
  39.         rs->timestamp=now_usec();
  40.         rs->status=0;
  41.         rs->tid=0;
  42.         return NULL;
  43. }

复制代码
上述代码实现了彻底异步的TCP代理服务器。
当然那个代理的代码量比较大,但是多线程异步处理就在这了。

论坛徽章:
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-04-16 16:35 |只看该作者
本帖最后由 windoze 于 2013-04-16 16:35 编辑

我这儿也有个多线程+asio+corotine的,包装了下iostream,代码看起来顺眼多了

https://github.com/windoze/coroserver

论坛徽章:
3
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:58:11数据库技术版块每日发帖之星
日期:2015-08-30 06:20:00
14 [报告]
发表于 2013-04-16 17:31 |只看该作者
回复 9# qinggeng


    恩,是的

论坛徽章:
3
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:58:11数据库技术版块每日发帖之星
日期:2015-08-30 06:20:00
15 [报告]
发表于 2013-04-16 17:33 |只看该作者
回复 5# yulihua49


    简单的使用多个线程跑 boost::asio::io_servier::run 即可。

论坛徽章:
3
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:58:11数据库技术版块每日发帖之星
日期:2015-08-30 06:20:00
16 [报告]
发表于 2013-04-16 17:35 |只看该作者
yulihua49 发表于 2013-04-16 16:22
这个,不扣题吧?人家说单线程asio,我说多线程asio。上述代码实现了彻底异步的TCP代理服务器。
当然那个 ...



这个代码又臭又长,充满了指针。

论坛徽章:
3
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:58:11数据库技术版块每日发帖之星
日期:2015-08-30 06:20:00
17 [报告]
发表于 2013-04-16 19:23 |只看该作者
把代码的说明加上了

论坛徽章:
15
射手座
日期:2014-11-29 19:22:4915-16赛季CBA联赛之青岛
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16赛季CBA联赛之四川
日期:2017-02-07 21:08:572015年亚冠纪念徽章
日期:2015-11-06 12:31:58每日论坛发贴之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-07-12 22:20:002015亚冠之浦和红钻
日期:2015-07-08 10:10:132015亚冠之大阪钢巴
日期:2015-06-29 11:21:122015亚冠之广州恒大
日期:2015-05-22 21:55:412015年亚洲杯之伊朗
日期:2015-04-10 16:28:25
18 [报告]
发表于 2013-04-17 11:10 |只看该作者
本帖最后由 yulihua49 于 2013-04-17 12:02 编辑
蔡万钊 发表于 2013-04-16 17:35
这个代码又臭又长,充满了指针。

长吗?才44行,这个长度都读不下去?以致臭汗淋漓?
指针,是C优于其他任何语言的利器。我们靠他提高效率。
epoll怎么提高的性能?event指针,usrdata指针。。。。立即获取,无需从数组中查找。。。。
再说,你的,不也是到处指针(m_request->。。。),使用C/C++,谁又能逃脱指针呢?
因为这是个实际的东西,作为原理,你把10-18行忽略,令task=NULL,进入等待事件的流程。在去掉关于错误处理和日志的部分,功能实体没有几行。

言归正传。
do_work()包含了一个异步结束后和新的异步开始前的所有操作,在新的异步开始前,设置状态,把fd装入事件,返回。
在do_work()里按照context的状态处理每个阶段的动作,算是所谓“协程”吗?
这个逻辑是清晰的,以至于无需调试,大家按规则办,流程就顺畅。
如果线程池只有一个线程,是否与你的东东差不多了?
当然我至少需要2个线程,一个守候非IO事件(就是10-18行的内容),一个守候IO事件。

仅仅交流交流,没有否定你的意思。

论坛徽章:
0
19 [报告]
发表于 2013-04-17 11:45 |只看该作者
我想请教楼主,您做过dns干扰吗,能不能指点一下

论坛徽章:
15
射手座
日期:2014-11-29 19:22:4915-16赛季CBA联赛之青岛
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16赛季CBA联赛之四川
日期:2017-02-07 21:08:572015年亚冠纪念徽章
日期:2015-11-06 12:31:58每日论坛发贴之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-07-12 22:20:002015亚冠之浦和红钻
日期:2015-07-08 10:10:132015亚冠之大阪钢巴
日期:2015-06-29 11:21:122015亚冠之广州恒大
日期:2015-05-22 21:55:412015年亚洲杯之伊朗
日期:2015-04-10 16:28:25
20 [报告]
发表于 2013-04-17 12:54 |只看该作者
本帖最后由 yulihua49 于 2013-04-17 12:59 编辑
蔡万钊 发表于 2013-04-16 17:33
回复 5# yulihua49


“那么,这个问题就复杂化了, “avbot 收到消息后,遍历这个列队执行消息发送” 这个做法,不可避免的带来了阻塞。好吧,异步遍历吧。

要是异步遍历还没遍历完,又来一个消息呢? 考虑这个问题,你会发疯的。因为异步,太多的细节需要考虑了。真的。”

这个交给epoll处理。


“好吧,又有个好主意了,为每个客户端建立一个列队,每次遍历就是把要发送的消息挂入列队即可。这样也不需要异步遍历了,同步就可以。解决了异步遍历的时候又来一个消息导致的痛苦的调度。

然后细分,考虑每个客户端,就是等待 “发送列队” 不为空!等等,一直这么等待也不行,如果客户断开了链接呢? 所以要 “同时等待发送列队不为空&&客户正常在线,并且已经发送了 HTTP 请求头部””


这个就由context,或称为session来解决。



----- 我的办法
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP