0

我运行这段代码

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 不是静态变量,则不会抛出任何错误。如果我在主函数中删除 t.flush(),它不会抛出任何错误。使用我在笔记中写的 std::lock_guard ,它旁边的行没有打印出来。我无法弄清楚我尝试过的案例的原因和差异是什么。

我使用 gcc 5.4.0 构建代码,使用 -O0

4

1 回答 1

0

static ttt t;

在 boost.fiber 的内部数据被破坏后,您在 main 中的静态ttt实例可能会被破坏。访问from可能context::active()会返回一个空指针。mutext::lock()~ttt()

编辑: boost.fiber 在内部使用一个线程本地静态来保存活动的纤程(为了启用从深度调用堆栈中挂起)。因为 ttl 被声明为静态,编译器可以以任意顺序破坏 ttl 实例和 boost.fiber 内部静态。

于 2017-07-04T14:39:24.180 回答