我运行此代码
class ttt {
public:
~ttt() {
LOG(INFO);
flush();
}
bool flush() {
//std::lock_guard<boost::fibers::mutex> lock(_mutex);
LOG(INFO);
_mutex.lock();
LOG(INFO);
auto ret = flush_nonlock();
LOG(INFO);
_mutex.unlock();
LOG(INFO);
return ret;
}
private:
bool flush_nonlock() {
LOG(INFO);
return std::rand()%2;
}
boost::fibers::mutex _mutex;
};
int main() {
static ttt t;
std::cout << t.flush() << std::endl;
return 0;
}
我得到了
terminate called after throwing an instance of 'boost::fibers::lock_error'
what(): boost fiber: a deadlock is detected: Resource deadlock avoided
它打印的最后一个日志是在_mutex.lock()之前。 如果t不是静态变量,则不会抛出任何错误。 如果我删除主func中的t.flush(),它不会抛出任何错误。 使用std :: lock_guard,就像我在笔记中写的那样,它旁边的行没有打印出来。 我无法弄清楚为什么以及我试过的案例的差异。
我使用gcc 5.4.0构建代码,使用-O0
答案 0 :(得分:0)
static ttt t;
在boost.fiber的内部数据被破坏后,main中的 ttt 的静态实例可能会被破坏。从context::active()
访问mutext::lock()
中的~ttt()
可能会返回空指针。
编辑:boost.fiber在内部使用一个保持活动光纤的线程本地静态(以便从深度调用堆栈启用挂起)。因为ttl被声明为static,编译器可以按任意顺序破坏ttl实例和boost.fiber internall static。