设为首页收藏本站

ISO/IEC C++ China Unofficial

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 691|回复: 3

【Flying with Boost.asio ③】协程到底干了些啥

[复制链接]

8

主题

64

帖子

269

积分

超级版主

Rank: 8Rank: 8

威望
12
经验
169
贡献
12
发表于 2015-12-16 10:23:10 | 显示全部楼层 |阅读模式
本帖最后由 nadesico19 于 2015-12-18 16:51 编辑

在 asio 中生成一个新的协程实例,所接受的函数签名是 void(boost::asio::yield_context),所有玄机都在这个 yield_context 中。

yield_context 中有一对重要的成员:


  1. detail::weak_ptr<callee_type> coro_; // callee_type -> boost::coroutines::push_coroutine<void>
  2. caller_type& ca_; // caller_type -> boost::coroutines::pull_coroutine<void>
复制代码


关于这里的 push_coroutine 与 pull_coroutine 分别扮演什么角色,通过一个例子不难理解:
  1. push_coroutine<void> coroutine([](pull_coroutine<void>& yield) {
  2.     std::cout << "Start" << std::endl;
  3.     yield(); // Yield until wake up by calling coroutine()
  4.     std::cout << "End" << std::endl;
  5. });

  6. while (coroutine) {
  7.     coroutine();
  8.     std::this_thread::sleep_for(2s);
  9. }
复制代码


可以看出 coro_ 和 ca_ 分别对应上例的 coroutine 和 yield。asio通过保存这一对成员,实现了在异步接口中挂起,在 Completion Handler 中唤醒的处理结构。

在自制异步接口时(参考第②回),这里有一个值得注意的地方: 协程会在当前执行线程被唤醒。

使用 asio 提供的原生异步接口时,可以保证挂起和唤醒时协程都处于同一个 io_service 内。而自制的时候可能会基于一些合理考虑,将异步处理交由其他 io_service 或线程池执行,此时如果需要在原始 io_service 内唤醒则需稍作处理。

虽然可以通过保存原始 io_service 的引用来解决这个问题,不过 yield_context 中的下面这个成员其实已经为我们开好了后门。


  1. Handler& handler_; // <- strand.wrap(&detail::default_spawn_handler)
复制代码


使用普遍方式(spawn 时使用 io_service 或 strand)生成的 handler_ 会是一个 wrapped_handler,这里面已经包含了协程生成时所在的 io_service,因此唤醒时只需:

  1. yield_context.handler_.dispatcher_.dispatch([]{ /* something like coroutine() */ })
复制代码


即可。

说到这个一句题外话,asio 实现中真是处处可见被注释掉的 private,好吧就此打住wwww

评分

参与人数 2威望 +2 贡献 +2 收起 理由
岩川黑鬼 + 1 + 1 系列好评。
LH_Mouse + 1 + 1 卖个萌!><

查看全部评分

回复

使用道具 举报

3

主题

74

帖子

283

积分

中级会员

Rank: 3Rank: 3

威望
9
经验
182
贡献
9
发表于 2015-12-16 18:48:32 | 显示全部楼层
真冷,挽个尊

点评

暖!【春ダァァァ♪】ヽ(。・∀・)人(・∀・。)ノルンル~ン*  发表于 2015-12-17 09:00
#if !idppc
/*
** float q_rsqrt( float number )
*/
float Q_rsqrt( float number )
{
        long i;
        float x2
回复 支持 反对

使用道具 举报

1

主题

10

帖子

44

积分

新手上路

Rank: 1

威望
0
经验
34
贡献
0
发表于 2015-12-18 17:59:48 | 显示全部楼层
真厉害
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|ISO/IEC C++ China Unofficial    

GMT+8, 2017-8-22 19:13 , Processed in 0.101041 second(s), 33 queries , Xcache On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表