я запускаю этот код
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 () в main func, он не выдаст никакой ошибки.
используйте std :: lock_guard, как я писал в заметках, строка рядом с ним не печатается.
Я не могу понять, почему и в чем разница в тех случаях, которые я пытался.
я строю код, используя gcc 5.4.0, с -O0
static ttt t;
ваш статический экземпляр ТТТ в основном может быть уничтожено после того, как внутренние данные boost.fiber были уничтожены. экранным context::active()
в mutext::lock()
от ~ttt()
может вернуть нулевой указатель.
edit: boost.fiber использует внутренне статическую локальную нить, удерживающую активное волокно (чтобы включить приостановку из глубокого стека вызовов). Так как ttl объявлен статическим, компилятор может уничтожить экземпляр ttl и внутреннюю статику boost.fiber в произвольном порядке.
Других решений пока нет …