2017-07-04 8 views
0

は、私はこのコード私は「::後押し::繊維をlock_error」だと

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を使用すると、その隣の行は印刷されません。 私が試したケースについて、なぜ、どのような違いがあるのか​​分かりません。

iは-O0

+0

'LOG(INFO)'は何をしていますか? – snoopy

+0

私はプログラムがエラーを投げる行を見つけようとします。 – beegerous

答えて

0

static ttt t;

boost.fiberの内部データが破壊された後、メインでTTTのあなたの静的インスタンスが破壊される可能性がありますし、コード使用のgcc 5.4.0を構築します。 context::active()mutext::lock()から~ttt()に返すと、NULLポインタが返されることがあります。

edit:boost.fiberは、アクティブなファイバを保持するスレッドローカルスタティックを内部的に使用します(ディープコールスタックからの中断を有効にするため)。 ttlは静的宣言されているため、コンパイラはttlインスタンスとboost.fiber internall staticを任意の順序で破棄できます。

+0

はすべてファイバのサスペンド機能に同じ問題がありますか?条件変数は? – beegerous

+0

@beegerous:私はあなたの前のコメントを理解していません - 問題はboost.fiberが現在アクティブなファイバを保持するスレッドローカルスタティックを内部的に使用していることです。アクティブファイバを一時停止して別のファイバーを再開させる必要があります(そうしないと、完全なコールスタックを通過させる必要があります)。 ttlはデストラクタでboost.fiberを呼び出します。 ttlは静的宣言されているので、boost.fiberからスタティックを破棄した後、コンパイラはttlデストラクタを自由に呼び出すことができます(静的インスタンスの破棄の順序はコンパイラによって異なります)。 – xlrg

+0

私は、静的デストラクタでfib::: condition_variable.wait()のような他のサスペンド機能を使用すると、同じエラーが発生するのでしょうか? destructor =。=でcondを使用する必要はないと思われます。私は問題がどこにあるのかよく知っていると思います。 – beegerous

関連する問題