libcopp更新 (merge boost 1.59 context)

libcopp更新 (merge boost 1.59 context)

之前由于兴趣写了一个协程框架,目前这个框架已经投入项目中使用。

这个框架的上下文部分是使用了boost.context,但是从开始写libcopp到现在,boost.context也更新了几个版本。而之前几次merge基本都是简单地跟进了*make_fcontext*和*jump_fcontext*两个函数,这次就再稍微翻了一遍其他部分的代码。

boost.context的变化

首先是它在非windows栈分配的时候,增加了valgrind的适配。不过boost.context里的不同平台的栈缓冲区其实结构差不多,但是boost的实现里给复制粘贴了很多遍,所以我就干脆把这些地方合并啦。减少了一些重复代码。

从1.58开始,boost.context增加了一个东东叫execute_context。看了下定位基本就是和我的libcopp里的copp部分(也就是不包括cotask)一样。但是它实现地比较简单,不像coppexecute_context的执行回调直接使用了boost::function,而copp里另外定义了一个*runner*。

不过从实现上来说,boost.context做了一个优化,就是把*runner*的*boost::function*直接放进了分配的栈里,减少了一次内存分配的操作,这么做的缺点就是,每个execute_context的创建,都必须复制调仿函数,如果仿函数复制会造成其他复制开销的话,那也是不可避免的。而copp的设计则是每个coroutine_context_container。都需要指定*runner*,而这些*runner*是可以被多个coroutine_context_container共享的。

在我们目前项目的使用上,会针对不同的消息类型定义一个处理的task。每次收到消息都会创建一个协程任务(对应有一个coroutine_context_container),但是处理的调用对象(就是task的action)对于某一种特定消息来说是唯一的。可以直接预创建,而不是每次收到消息的时候重新创建。所以copp的方式显然更适合我们的需求。

另外execute_contextcopp一样,提供了获取当前执行对象的功能。并且实现方法都一样,是使用了thread local storage。不过有一点不同的是,boost.context直接使用了c++11的关键字,而我的libcopp中是会根据环境选择的。因为在使用过程中,我们发现有些平台或者环境不支持线程本地存储,比如Android。所以在这些平台中,boost.contextexecute_context会不可用,而libcopp只是不能多线程运行。

最后就是execute_context增加了对Windows Fiber(纤程)的支持。在开启纤程的情况下,完全使用了另一套做法。由于短期内我没有这方面的需求,而且Windows vc下目前使用原来的方式也没什么问题。所以短期内不会merge这部分内容。(另外只是代码里看到了,貌似没看到什么地方会加上开启纤程支持的宏定义)

PS: boost的汇编里默默地把一个系统宏换成了带BOOST_前缀的宏,然后由环境检测工具来判断是否追加这个宏。差点漏掉的说。

变更列表

libcopp的近期的变动如下: 1. 跟进上下文初始化和切换的汇编代码更新 2. 跟进增加了pe下的gnu as支持的上下文汇编支持(但是貌似不太正常) 3. 跟进增加了valgrind支持 4. 平台和工具链判定逻辑优化,目前采用和boost一样的层级 5. 合并工具的符号替换增加BOOST_EXPORT符号 6. this_xxx接口返回普通指针而非智能指针 > 因为在实际使用过程中发现在保护性结束协程任务的过程中,可能会先释放智能指针,再回调析构。这种情况下,this_xxx接口调用获取智能指针的时候会导致失败而崩溃。

后续计划

  1. 考虑直接使用boost.context的汇编部分的接口 > 这么做得考虑好几个问题:一是先想办法解决如何编译选项一致的问题,因为环境的不同,boost会给出不同的红定义来控制一些行为(比如是否支持valgrind、是否支持),并且必须保持和我的库一致才行;第二就是必须要能够剥离boost的头文件,只依赖库文件。boost的头文件太多太庞大了。
  2. 抽空也支持Windows纤程
  3. 增加一些防止接口被勿用的保护

Written with StackEdit.

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏码农二狗

防止因事务未提交导致的死锁

1054
来自专栏编程

PHP7 下的协程实现

前言 相信大家都听说过『协程』这个概念吧。 但是有些同学对这个概念似懂非懂,不知道怎么实现,怎么用,用在哪,甚至有些人认为yield就是协程! 我始终相信,如果...

3578
来自专栏C/C++基础

Google C++编程风格指南(一)之头文件的相关规范

一个良好的编程规范和风格是一名程序猿成熟的标志。规范的编码可以减少代码冗余,降低出错概率,便于代码管理和代码交流等等,事实上,其作用远不止这些,我们要牢记编码规...

1651
来自专栏阿杜的世界

Spring Boot:定制URL匹配规则

构建web应用程序时,并不是所有的URL请求都遵循默认的规则。有时,我们希望RESTful URL匹配的时候包含定界符“.”,这种情况在Spring中可以称之为...

1343
来自专栏测试驿栈

Jmeter(七)_if控制器+循环控制器+计数器控制接口分支

最近查阅了一下网上关于if控制器的文章,大同小异,几乎找不到原创,于是决定自己写一篇

1.2K2
来自专栏ImportSource

并发编程-什么是线程安全?

定义“线程安全”这个概念是一个非常复杂的事情。越是正式而严肃的描述它越是复杂难懂,不仅没办法提供一些实际的指导,而且还没法有一个直观的理解。还有一些不太正式的描...

3787
来自专栏乐沙弥的世界

mongoDB简介及关键特性

861
来自专栏FreeBuf

挖洞经验 | 命令注入突破长度限制

0x01 背景 很多时候,在我们历经千辛万苦挖掘出一个漏洞或者找到一个利用点的时候,却因为一些egg hurt的限制,导致get shell或者send pay...

24910
来自专栏noteless

[零] Java 语言运行原理 JVM原理浅析 入门了解简介 Java语言组成部分 javap命令使用

https://docs.oracle.com/javase/specs/index.html

1032
来自专栏coding for love

在线商城项目11-商品列表页的排序实现

请求后台接口会带上三种排序参数default,priceDown和priceUp。另外,如果不带参数,我们默认排序也是default。 这里,我们做一个简单的...

812

扫码关注云+社区

领取腾讯云代金券