为什么我的 boost fiber 代码死锁
Why my boost fiber code is deadlocking
我已经尝试了 boost::fibers::barrier,但我找不到以下代码死锁的原因:
#include <boost/fiber/all.hpp>
#include <iostream>
#include <boost/range/algorithm/generate.hpp>
#include <boost/range/algorithm/for_each.hpp>
void barrier_test()
{
boost::fibers::barrier barrier(2);
std::vector<boost::fibers::fiber> myfibers(4);
boost::generate(myfibers, [&barrier]() {
return boost::fibers::fiber([](boost::fibers::barrier& barrier) {
static unsigned id_inc = 0;
const auto id = ++id_inc;
std::cout << "fiber id: " << boost::this_fiber::get_id() << " - local id: " << id << std::endl;
barrier.wait();
std::cout << "barrier passed, fiber id: " << boost::this_fiber::get_id() << " - local id: " << id << std::endl;
}, std::ref(barrier) );
});
std::cout << "main fiber: " << boost::this_fiber::get_id() << std::endl;
boost::for_each(myfibers, [](boost::fibers::fiber& aFiber) {
aFiber.join();
});
std::cout << "end of program" << std::endl;
}
如果我将启动设置为 "dispatch" 它可以通过。所以它有一些运行的顺序,但我不知道哪里出了问题。所以我试着想象锁定是如何在幕后发生的,得到什么运行,等等,但我就是找不到,为什么原始代码无法完成。
如果有人不想尝试,让我把我看到的输出放在这里:
main fiber: 000000000042C960
fiber id: 000000000042C6E0 - local id: 1
fiber id: 000000000044CF60 - local id: 2
barrier passed, fiber id: 000000000044CF60 - local id: 2
fiber id: 000000000045D020 - local id: 3
fiber id: 000000000046D0E0 - local id: 4
barrier passed, fiber id: 000000000046D0E0 - local id: 4
barrier passed, fiber id: 000000000045D020 - local id: 3
我已经将我的自定义测试调度程序算法复制到测试代码中,我看到,一段时间后,运行 没有光纤可用,本地 id 1 光纤根本就没有继续。
Boost版本为1.63,预编译包为visual studio 2015,编译为64位
改变
boost::fibers::barrier barrier(2);
至
boost::fibers::barrier barrier(4);
或者等到boost-1.64发布
代码对我来说永远不会死锁,但有一些变数需要考虑:我使用的是 mac,我使用的是 boost 1.64,我可能以不同的方式编译了 boost。
boost? ./fibers
main fiber: 0x7f877cc02bc0
fiber id: 0x100cbce00 - local id: 1
fiber id: 0x100ebce00 - local id: 2
barrier passed, fiber id: 0x100ebce00 - local id: 2
fiber id: 0x100fbce00 - local id: 3
fiber id: 0x1010bce00 - local id: 4
barrier passed, fiber id: 0x1010bce00 - local id: 4
barrier passed, fiber id: 0x100cbce00 - local id: 1
barrier passed, fiber id: 0x100fbce00 - local id: 3
end of program
仅供参考 - 我编译并 运行 像这样:
./bootstrap.sh --prefix=/Users/john/boost/boost_installation --without-libraries=python
./b2 install cxxflags='-std=c++14' -j 6 threading=multi variant=release link=shared stage --reconfigure
g++ -std=c++14 -I/Users/john/boost/boost_installation/include/ -L/Users/john/boost/boost_installation/lib -lboost_context -lboost_system -lboost_thread -lpthread -lboost_fiber -o fibers fibers.cpp
DYLD_LIBRARY_PATH=/Users/john/boost/boost_installation/lib
./fibers
这可能不是你需要的,但因为它对我有用,所以我帮不了你。
我在 Debian/unstable 上用 boost-1.63.0 试过这个程序,我可以确认这个问题。当我 运行 报告程序使用 valgrind 访问未初始化的内存时,后来也报告了无效读取,所以我猜问题出在那个特定的提升版本上。
我已经尝试了 boost::fibers::barrier,但我找不到以下代码死锁的原因:
#include <boost/fiber/all.hpp>
#include <iostream>
#include <boost/range/algorithm/generate.hpp>
#include <boost/range/algorithm/for_each.hpp>
void barrier_test()
{
boost::fibers::barrier barrier(2);
std::vector<boost::fibers::fiber> myfibers(4);
boost::generate(myfibers, [&barrier]() {
return boost::fibers::fiber([](boost::fibers::barrier& barrier) {
static unsigned id_inc = 0;
const auto id = ++id_inc;
std::cout << "fiber id: " << boost::this_fiber::get_id() << " - local id: " << id << std::endl;
barrier.wait();
std::cout << "barrier passed, fiber id: " << boost::this_fiber::get_id() << " - local id: " << id << std::endl;
}, std::ref(barrier) );
});
std::cout << "main fiber: " << boost::this_fiber::get_id() << std::endl;
boost::for_each(myfibers, [](boost::fibers::fiber& aFiber) {
aFiber.join();
});
std::cout << "end of program" << std::endl;
}
如果我将启动设置为 "dispatch" 它可以通过。所以它有一些运行的顺序,但我不知道哪里出了问题。所以我试着想象锁定是如何在幕后发生的,得到什么运行,等等,但我就是找不到,为什么原始代码无法完成。
如果有人不想尝试,让我把我看到的输出放在这里:
main fiber: 000000000042C960
fiber id: 000000000042C6E0 - local id: 1
fiber id: 000000000044CF60 - local id: 2
barrier passed, fiber id: 000000000044CF60 - local id: 2
fiber id: 000000000045D020 - local id: 3
fiber id: 000000000046D0E0 - local id: 4
barrier passed, fiber id: 000000000046D0E0 - local id: 4
barrier passed, fiber id: 000000000045D020 - local id: 3
我已经将我的自定义测试调度程序算法复制到测试代码中,我看到,一段时间后,运行 没有光纤可用,本地 id 1 光纤根本就没有继续。
Boost版本为1.63,预编译包为visual studio 2015,编译为64位
改变
boost::fibers::barrier barrier(2);
至
boost::fibers::barrier barrier(4);
或者等到boost-1.64发布
代码对我来说永远不会死锁,但有一些变数需要考虑:我使用的是 mac,我使用的是 boost 1.64,我可能以不同的方式编译了 boost。
boost? ./fibers
main fiber: 0x7f877cc02bc0
fiber id: 0x100cbce00 - local id: 1
fiber id: 0x100ebce00 - local id: 2
barrier passed, fiber id: 0x100ebce00 - local id: 2
fiber id: 0x100fbce00 - local id: 3
fiber id: 0x1010bce00 - local id: 4
barrier passed, fiber id: 0x1010bce00 - local id: 4
barrier passed, fiber id: 0x100cbce00 - local id: 1
barrier passed, fiber id: 0x100fbce00 - local id: 3
end of program
仅供参考 - 我编译并 运行 像这样:
./bootstrap.sh --prefix=/Users/john/boost/boost_installation --without-libraries=python
./b2 install cxxflags='-std=c++14' -j 6 threading=multi variant=release link=shared stage --reconfigure
g++ -std=c++14 -I/Users/john/boost/boost_installation/include/ -L/Users/john/boost/boost_installation/lib -lboost_context -lboost_system -lboost_thread -lpthread -lboost_fiber -o fibers fibers.cpp
DYLD_LIBRARY_PATH=/Users/john/boost/boost_installation/lib
./fibers
这可能不是你需要的,但因为它对我有用,所以我帮不了你。
我在 Debian/unstable 上用 boost-1.63.0 试过这个程序,我可以确认这个问题。当我 运行 报告程序使用 valgrind 访问未初始化的内存时,后来也报告了无效读取,所以我猜问题出在那个特定的提升版本上。