免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3506 | 回复: 4
打印 上一主题 下一主题

[C++] 在阻塞函数中等待异步数据包结果 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2015-06-22 18:02 |只看该作者 |倒序浏览
开发环境: boost asio + 最新 visual studio,所以什么类库都能使用。

需求:一个第三方的服务器, 我在写一个中间层dll,用导出函数形式,给用户使用。 情况是:

1. 协议用一个tcp长链接,所有收发都在这个长连接上。
2. 可能同时发送/接收多个包,为避免阻塞影响性能,所以用的异步操作 async_read / async_write
3. 服务器返回包的顺序不一定按照发送时的顺序,比如发送 A, B 到服务器, 收到的包可能是 回应B, 回应A
4. 因此每个包头上用一个序号(seq_id)来标识, 比如发送一个包,带上 seq_id==123,然后就等服务器返回一个带着seq_id==134的包

问题是,这种异步读写方式需要callback,用户不喜欢callback,希望阻塞方式调用dll接口,如某导出函数用来发送文字消息:

  1. void say_hello(...) {
  2.   // async_write 在长连接上发送到服务器,假设seq_id==123
  3.   // 这里怎么阻塞等待服务器返回seq_id==123的包
  4.   // ...
  5. }
复制代码

论坛徽章:
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
2 [报告]
发表于 2015-06-22 20:33 |只看该作者
本帖最后由 yulihua49 于 2015-06-22 20:51 编辑
aj3423 发表于 2015-06-22 18:02
开发环境: boost asio + 最新 visual studio,所以什么类库都能使用。

需求:一个第三方的服务器, 我在 ...

使用coroutine. 问问windoze吧,他内行。
大概是:
  1. NBLOCK_write();
  2. if(没完) yield();
  3. ....
复制代码
http://bbs.chinaunix.net/thread-4148586-1-1.html
看13楼。

你的问题也不是coroutine能解决的,应该使用MQ(消息队列)。

论坛徽章:
0
3 [报告]
发表于 2015-06-23 00:43 |只看该作者
谢谢 yulihua49,这两天了解了下coroutine,能把异步变成同步。看了上面链接帖子,和我的需求看似很像,但实际完全不同,我并不是在多个线程里接收消息,而是在一个地方接收消息,然后根据里面的 seq_id 分发给其他不同线程。 所以并不完全是coroutine的应用场景(我对这个不熟,如果有错请指出)
我同时在stackoverflow上发了帖子,老外给了正解:居然说我没有发链接的权限。。google 搜 dispach response packet according to packet sequence id 就可以搜到帖子链接
用 std::future 作为发送数据包函数的返回值,扔给其他线程。

论坛徽章:
0
4 [报告]
发表于 2015-06-23 09:39 |只看该作者
看了下,如果用户不希望用回调,那么你就再封装下, 具体可借鉴下 libevent的设计思路, 采用观察者模式来解决这个问题,如果从效率上讲(多并发情况),使用异步非阻塞方式一定优于阻塞模式

论坛徽章:
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
5 [报告]
发表于 2015-06-23 11:35 |只看该作者
本帖最后由 yulihua49 于 2015-06-23 11:39 编辑
aj3423 发表于 2015-06-23 00:43
谢谢 yulihua49,这两天了解了下coroutine,能把异步变成同步。看了上面链接帖子,和我的需求看似很像,但实 ...

所以我说你的问题不是coroutine能解决的,只是给你一个思路。
鉴于服务器返回结果的无序性,callback好像没办法规避。
即使基于MQ,也还是要callback。
用coriutine的思路做包装?需要你自己创新了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP