ドキュメントによると
現在実行中のファイバーは、マネージャーに制御を渡す何らかの操作を呼び出すまで、制御を保持します。
考えられる操作は 1 つだけboost::this_fiber::yield
です。これにより、ファイバーからファイバーへの制御の切り替えが発生する可能性があります。ただし、次のようなものを実行すると
bf::fiber([](){std::cout << "Bang!" << std::endl;}).detach();
bf::fiber([](){std::cout << "Bung!" << std::endl;}).detach();
次のような出力が得られます
バン!バン!
\n
\n
<<
これは、オペレータ間で、あるファイバから別のファイバへと制御が渡されたことを意味します。それはどのように起こりますか?なんで?boost::fiber
ライブラリのコンテキストで、ファイバーからファイバーへの制御の受け渡しの一般的な定義は何ですか?
EDIT001: コードなしでは逃げられない:
#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 - -ナン
0.503334 3 - 4 - 0.861055
0.971884 5 - 6 - 0.968536 -
ナン 7 - 8 - 0.921959
0.9580699
- 10 - 0.948075
0.961811