问题标签 [boost-coroutine]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
977 浏览

c++ - boost中的协程局部变量

我正在寻找类似于线程局部变量的东西,但对于 boost::corotine (实际上我使用 boost:asio::spawn)。考虑以下代码:

我想在the_magic_request_id初始化请求时将其设置为某个值,这将类似于“当前请求 ID”。

没有这个,我必须传递the_magic_request_id给每个功能和每个登录项目的模块。some_function只是一个例子,实际上我有很多类,它们做不同的工作,但它们都需要yield_context并且the_magic_request_id为了创建一个实例。我想简化这些类的接口。

可能可以设置“on_sleep”和“on_resume”钩子,这将设置一个全局变量?或者 boost::coroutine 已经为此提供了一些现成的用户机制?没有在文档中找到可用的东西。

0 投票
0 回答
259 浏览

c++ - 延迟协程产量

我的问题似乎源于这样一个事实,即openssl 没有像服务器名称指示(SNI)这样的回调继续传递样式,但我正试图强制其中一个。

我想避免在读取客户端 SSL hello 时阻塞工作线程,并避免在等待服务器 ssl 握手完成时拒绝返回 SNI 回调时阻塞工作线程(这样我就可以重新签署服务器证书)。

对于使用openssl 包装器的asiobsaed 重新签名 SSL 代理。boost::asio::ssl::stream

SSL_CTX_set_tlsext_servername_*在与客户端进行 SSL 协商期间,我使用助手来获取回调。

目前请确保我在 aboost::asio::spawn上的 lambda 中使用协程和握手strand。我使用服务器名称指示回调(适当地包装),以便我可以在服务器握手期间阻止客户端握手,但不会阻止工作线程(协同程序将暂停。

但我意识到与客户端的 ssl 握手会阻止它完成的工作线程。

我尝试与客户进行异步握手:

但是在 SNI 处理程序包装期间,程序在 yield 中出现了段错误。

毫无疑问,这是因为非阻塞握手不会调用协程上的 SNI 处理程序——它可以做到这一点的唯一方法(不阻塞工作线程)是如果它的所有内部处理程序都在协程上调用,但是我知道它使用内部链来完成自己的工作。

加载所有共享库符号(即使对于 libstdc++ 等),堆栈跟踪是:

我希望这是清除故障期间的堆栈跟踪。

要在同一个协程上调用 SNI 处理程序,我认为我需要使所有 ssl::stream 中间回调发生在该协程上。有没有直接的方法可以做到这一点?

我想知道 boost::ssl 是否可以在它自己的链中调用它的处理程序,但仍然在协程堆栈上,这是唯一的解决方法,但我不知道带有处理程序的 asio_handler_invoke 业务是否有足够的魔力来导致这种情况发生,即使这是可能的。如何嵌套 asio_handler_invoke 以在协程(本身为 strand-y)和通过内部链上运行。

我还应该在示例的最后一行中使用 asio_invoke_handler 吗?

0 投票
0 回答
1200 浏览

c++ - 构建 Boost.Coroutines2 示例

我正在尝试构建 Boost 1.59 coroutine 和 coroutine2 示例。
我使用 b2(完整构建)构建了 boost,并且正在使用 CMake 生成一个 VC2015 项目来构建示例。

所有协程示例都可以正常构建和运行,但是我在coroutine2示例中出现链接错误。

我的CMakeLists.txt文件很简单,只需找到 boost,包含头文件并链接到 boost 库:

链接似乎无法找到 boost::system::system_category。
这是我的错误日志:

我究竟做错了什么?

0 投票
0 回答
196 浏览

c++ - 在 boost::asio::spawned 协程中访问成员变量

我正在尝试在现有代码库的深处添加一些异步操作,这些操作在使用 pion 实现的 Web 服务器中调用(它本身使用 boost::asio)。

当前代码需要在没有 io_service 可用的上下文中继续运行,所以我做了以下操作,其中 Foo::bar 是现有代码库的主要入口点,handleRequest 是 pion 请求处理程序:

这似乎有效,因为它最终在协程中运行 Foo::barCommon,但是现有代码一旦尝试访问 Foo 成员变量就会崩溃。我在这里想念什么?

编辑:为了清楚起见,handleRequest 中获取的指针指向一个堆分配的 Foo 对象,其生命周期与服务器进程的生命周期相匹配。

0 投票
0 回答
674 浏览

boost-coroutine - 提升协程性能:对称与非对称

查看Boost.Coroutine 的性能页面,构建对称协程似乎比非对称协程便宜得多,大约 50 倍。这似乎令人惊讶,因为对称协程似乎提供了更通用的抽象。不对称协程中是否有一些功能可以证明这种成本是合理的?

我还应该补充一点,在不对称协程的上下文中,构建成本大约是上下文切换成本的 500 倍,因此它很容易成为应用程序的瓶颈。

0 投票
2 回答
1711 浏览

c++ - C++ 绿色线程的堆栈分配

我正在对 C++ 绿色线程进行一些研究,主要是boost::coroutine2类似的 POSIX 函数makecontext()/swapcontext(),并计划在boost::coroutine2. 两者都需要用户代码为每个新函数/协程分配一个堆栈。

我的目标平台是 x64/Linux。我希望我的绿色线程库适用于一般用途,因此堆栈应根据需要扩展(合理的上限很好,例如 10MB),如果未使用太多内存时堆栈可以收缩(不需要),那就太好了)。我还没有找到合适的算法来分配堆栈。

经过一番谷歌搜索,我自己想出了几个选项:

  1. 使用编译器实现的拆分堆栈(gcc -fsplit-stack),但拆分堆栈有性能开销。由于性能原因,Go 已经远离了拆分堆栈。
  2. 分配一大块内存,mmap()希望内核足够聪明,不分配物理内存,只在访问堆栈时分配。在这种情况下,我们受内核的支配。
  3. 预留一个大的内存空间mmap(PROT_NONE)并设置一个SIGSEGV信号处理程序。在信号处理程序中,当SIGSEGV由堆栈访问引起时(访问的内存在保留的大内存空间内),分配所需的内存mmap(PROT_READ | PROT_WRITE)。这是这种方法的问题:mmap()不是异步安全的,不能在信号处理程序中调用。它仍然可以实现,但非常棘手:在程序启动期间创建另一个线程用于内存分配,并用于pipe() + read()/write()将内存分配信息从信号处理程序发送到线程。

关于选项 3 的更多问题:

  1. 我不确定这种方法的性能开销,当内存空间由于数千次mmap()调用而极度碎片化时,内核/CPU 的性能如何?
  2. 如果在内核空间中访问未分配的内存,这种方法是否正确?例如,何时read()调用?

绿色线程的堆栈分配还有其他(更好的)选项吗?在其他实现(例如 Go/Java)中如何分配绿色线程堆栈?

0 投票
1 回答
1537 浏览

c++ - 增强多核协程

我的 tcp 服务器基于这个boost coroutine server example

每秒有很多请求,服务器有两个核心但只使用一个,在任务管理器的性能选项卡中它永远不会超过 50% cpu,并且一个核心始终是空闲的: 在此处输入图像描述

如何使 boost::coroutine 与多核一起工作?

我刚刚想出了一个添加thread_pool的解决方案:

现在代码似乎在telnet 127.0.0.1 80两次后以 100% cpu 运行。

但是使用多核协程的常用方法是什么?

0 投票
1 回答
756 浏览

c++ - 在协程执行之间强制休眠

我目前有一些同步 C++ 代码,它们以顺序方式执行一些耗时的任务。我正在考虑使用 Boost 协程将其重构为并行任务。

任务的核心是对外部库的调用,该库提供同步 API(它当前正在使用)或异步 API,必须定期轮询以执行操作并确定操作是否已完成。API 不是线程安全的,但如果使用异步版本,只要轮询 API 本身不被并发调用,它就可以处理同时发生的多个请求。

(因为我不想要任何线程转移,看来我应该直接使用协程 API 而不是使用 ASIO 包装器或类似的,但我愿意被说服。我现在也在使用 Boost 1.55 ,因此 Fiber 库不可用;但这种用法似乎也有点过头了。)

目前我对协程的主要问题是我不确定如何在轮询中实现节流——假设我有 100 个任务要并行运行;我希望它对所有 100 个任务进行一次轮询,然后让线程休眠指定的时间。一些任务可能比其他任务完成得更快,因此稍后它可能仍会在每个循环中轮询 40 个任务,然后休眠相同的时间。我不希望它在没有干预睡眠的情况下连续两次轮询同一任务。

0 投票
2 回答
4091 浏览

c++ - Boost.Coroutine 和 Boost.Coroutine2 的区别

Boost.CoroutineBoost.Coroutine2之间的主要区别是什么?

0 投票
1 回答
330 浏览

c++ - 与 boost::property_tree XML 解析器一起使用时 boost::coroutine 库中的崩溃

我正在使用Simple-Web-Server库来创建简单的 Web 服务,以便将XML转换为JSON,反之亦然。反过来,它使用了几个boost库以及boost::coroutine。对于XML<->JSON转换,我使用boost::property_tree库进行中间表示。这是代码:

JSONXML的转换工作正常,但相反会导致程序崩溃。当我不在服务器回调中使用boost::property_treeXML解析器时,程序运行良好。是执行的结果。GDB回溯。最后是Valgrind输出。

使用的boost库版本是1.58.0但在最新版本1.61.0中观察到相同的结果。使用Simple-Web-Server的1.4.2版。