boost :: fiber调度-何时以及如何 [英] boost::fiber scheduling - when and how

查看:491
本文介绍了boost :: fiber调度-何时以及如何的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据文档

当前运行的光纤保留控制权,直到它调用某些 将控制权传递给经理的操作

the currently-running fiber retains control until it invokes some operation that passes control to the manager

我只能考虑一项操作-boost::this_fiber::yield,这可能会导致控制从光纤切换到光纤.但是,当我运行类似

I can think about only one operation - boost::this_fiber::yield which may cause control switch from fiber to fiber. However, when I run something like

bf::fiber([](){std::cout << "Bang!" << std::endl;}).detach();
bf::fiber([](){std::cout << "Bung!" << std::endl;}).detach();

我得到类似

B!B!
\ n
\ n

Bang!Bung!
\n
\n

这意味着控制已在<<个运算符之间从一根光纤传递到另一根光纤.它怎么可能发生?为什么?在boost::fiber库的上下文中,控制从光纤传递到光纤的一般定义是什么?

Which means control was passed between << operators from one fiber to another. How it could happen? Why? What is the general definition of controll passing from fiber to fiber in the context of boost::fiber library?

EDIT001: 没有代码就无法逃脱:

EDIT001: Cant get away without code:

#include <boost/fiber/fiber.hpp>
#include <boost/fiber/mutex.hpp>
#include <boost/fiber/barrier.hpp>
#include <boost/fiber/algo/algorithm.hpp>
#include <boost/fiber/algo/work_stealing.hpp>

namespace bf = boost::fibers;

class GreenExecutor
{
    std::thread worker;
    bf::condition_variable_any cv;
    bf::mutex mtx;
    bf::barrier barrier;
public:
    GreenExecutor() : barrier {2}
    {   
        worker = std::thread([this] {
            bf::use_scheduling_algorithm<bf::algo::work_stealing>(2);
            // wait till all threads joining the work stealing have been registered
            barrier.wait();
            mtx.lock();
            // suspend main-fiber from the worker thread
            cv.wait(mtx);
            mtx.unlock();
        });
        bf::use_scheduling_algorithm<bf::algo::work_stealing>(2);
        // wait till all threads have been registered the scheduling algorithm
        barrier.wait();
    }

    template<typename T>
    void PostWork(T&& functor)
    {
        bf::fiber {std::move(functor)}.detach();
    }

    ~GreenExecutor()
    {
        cv.notify_all();
        worker.join();
    }
};

int main()
{
    GreenExecutor executor;
    std::this_thread::sleep_for(std::chrono::seconds(1));
    int i = 0;
    for (auto j = 0ul; j < 10; ++j) {
        executor.PostWork([idx {++i}]() {
            auto res = pow(sqrt(sin(cos(tan(idx)))), M_1_PI);
            std::cout << idx << " - " << res << std::endl;
        });
    }
    while (true) {
        boost::this_fiber::yield();
    }
    return 0;
}

输出

2-1--nan
0.503334 3-4-0.861055
0.971884 5-6-0.968536
-nan 7-8-0.921959
0.9580699
-10-0.948075
0.961811

2 - 1 - -nan
0.503334 3 - 4 - 0.861055
0.971884 5 - 6 - 0.968536
-nan 7 - 8 - 0.921959
0.9580699
- 10 - 0.948075
0.961811

推荐答案

好吧,我错过了几件事,首先,我的结论基于对boost::fiber
中的东西如何工作的误解 问题中提到的构造函数中的行 bf::use_scheduling_algorithm<bf::algo::work_stealing>(2);
正在在创建GreenExecutor实例的线程中(在主线程中)安装调度程序,因此,当启动两个worker fiber时,我实际上是在启动两个线程,它们将处理提交的fiber会异步处理这些fibers从而混合std::cout输出.没什么魔术,一切都按预期工作,boost::fiber::yield仍然是将控制权从一根光纤传递到另一根光纤的唯一选择

Ok, there were a couple of things I missed, first, my conclusion was based on misunderstanding of how stuff works in boost::fiber
The line in the constructor mentioned in the question bf::use_scheduling_algorithm<bf::algo::work_stealing>(2);
was installing the scheduler in the thread where the GreenExecutor instance was created (in the main thread) so, when launching two worker fibers I was actually initiating two threads which are going to process submitted fibers which in turn would process these fibers asynchronously thus mixing the std::cout output. No magic, everything works as expected, the boost::fiber::yield still is the only option to pass control from one fiber to another

这篇关于boost :: fiber调度-何时以及如何的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆