首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在work_stealing中使用boost.fibers调度程序

如何在work_stealing中使用boost.fibers调度程序
EN

Stack Overflow用户
提问于 2017-12-12 13:32:40
回答 1查看 1.4K关注 0票数 2

我正在尝试构建一个通用的任务系统,在这个系统中,我可以发布在任意线程上执行的任务。在之前的尝试中,我经常没有线程,因为它们会在某个时候阻塞。因此,我正在尝试促进纤维;当一根纤维阻塞,线程可以自由地在其他纤维上工作,听起来很完美。

偷工作算法似乎对我的目的来说是理想的,但我很难使用它。在这个例子中,代码纤维被创建,只有这样线程和调度器才被创建,所以所有的纤维实际上都在所有的线程上被执行。但是我想稍后启动光纤,到那时所有其他线程都会被无限期地挂起,因为它们没有任何工作。我没有找到任何方法再次唤醒他们,我所有的纤维只能在主线程上执行。“通知”似乎是调用的方法,但我看不到有任何方法能够真正找到一个算法的实例。

我试着保存指向该算法所有实例的指针,这样我就可以调用notify(),但这并没有真正的帮助;大多数情况下,工作线程中的算法不能从主线程中窃取任何东西,因为下一个是dispatcher_context。

我可以禁用“挂起”,但是线程正忙着等待,这不是一个选项。

我还尝试了共享工作算法。同样的问题,一旦一根线找不到一根纤维,它就再也不会醒来了。我尝试了相同的黑客手动调用通知(),同样的结果,非常不可靠。

我试着使用频道,但是AFAICT,如果有光纤在等待,当前的上下文就会“跳过”,运行等待的光纤,挂起当前的光纤。

简而言之:我发现很难在另一个线程上可靠地运行一个光纤。在分析时,大多数线程只是在等待一个condition_variable,尽管我确实创建了大量的光纤。

作为一个小测试用例,我正在尝试:

代码语言:javascript
运行
复制
std::vector<boost::fibers::future<int>> v;

for (auto i = 0; i < 16; ++i)
    v.emplace_back(boost::fibers::async([i] {
       std::this_thread::sleep_for(std::chrono::milliseconds(1000));
       return i;
    }));

int s = 0;
for (auto &f : v)
    s += f.get();

我故意使用this_thread::sleep_for来模拟CPU忙。

对于16个线程,我希望这段代码能在1s中运行,但大多数情况下它是16 s。我能够让这个具体的例子在1中真正运行,只是黑客入侵一些东西;但是没有办法感觉“正确”,也没有办法在其他情况下有效,它总是要手工制作到一个特定的场景中。

我认为这个例子应该和work_stealing算法一样工作;我缺少了什么呢?这只是滥用纤维吗?我如何可靠地实现这一点?

谢谢你,迪克斯

EN

回答 1

Stack Overflow用户

发布于 2017-12-13 14:40:06

boost.fiber包含一个使用work_stealing算法的示例(示例/work_stealing.cpp)。

  1. 您必须在每个应该处理/偷取光纤的工作线程上安装该算法。boost::fibers::use_scheduling_algorithm< boost::fibers::algo::work_stealing >( 4); // 4 worker-threads
  2. 在处理任务/纤维之前,必须等到所有的工作线程都在协商时注册。该示例为此使用了一个障碍。
  3. 您需要使用条件变量来完成所有工作/任务的空闲操作。

看看使用工作线程运行 (boost文档)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47773921

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档