2017-11-21 12 views
0

私は自分のプロジェクト用にマルチスレッドサーバーを構築しています。
条件変数とロックを使用しています。
グローバル変数として条件変数cvを持ち、クラスメンバーとしてmutex _mtxReceivedMessagesを持っています。condition_variableが待機しているときに閉じるときにC++プログラムがクラッシュするのを止めるには?

これは、ユーザーのメッセージを待つ関数です。

void Server::handleReceivedMessages() 
{ 
while (1) 
{ 
    std::unique_lock<std::mutex> lck(_mtxReceivedMessages); 
    while (_queRcvMessages.size() == 0) cv.wait(lck); // As long as there are 0 messages in the queue 
} 
} 

これはCV通知を呼び出す関数です:

void Server::addReceivedMessage(ReceivedMessage* msg) 
{ 
    _queRcvMessages.push(msg); // Adds the message to the queue 
    cv.notify_all(); // Unlockes all locked functions 
} 

問題は、私がしようとした場合閉鎖するということですプログラムは、(addReceivedMessage関数が呼び出される前に)関数handleReceivedMessagesが待機している間に、プログラムがクラッシュすると、
が削除されますが、行を削除した場合:

while (_queRcvMessages.size() == 0) cv.wait(lck); // As long as there are 0 messages in the queue 

プログラムはうまく終了します。

プログラムがクラッシュします。Nuvola.exeの0x7748507C(ntdll.dll)で未処理の例外が発生しました:0xC000000D:無効なパラメータがサービスまたは関数に渡されました。

何が問題なのですか?

+0

:(。それは1を持っている場合は、joinに、サーバのスレッドが必要な場合があります)

あなたhandleReceivedMessages機能は、より多くのようになります。 – VTT

+0

ブロッキングキューから物事を取り出すスレッドを止める私の好きな方法は、スレッドのメインループがその既知のアドレスか特殊な内容のどちらかで認識する識別オブジェクトです。スレッドは、キューからポップする各オブジェクトを調べ、ポイズンピルオブジェクトを見ると、クリーンアップと終了を知っています。 –

答えて

5

クリーンシャットダウンが必要な場合は、すべてに設計する必要があります。サーバーにはシャットダウン機能が必要です(デストラクタになる可能性があります)。そして、あなたのhandleReceivedMessages関数は、シャットダウン時に停止する方法が必要です。

たとえば、Serverクラスにbool shutdown;を追加できます。クラスをシャットダウンするには、mutexを取得し、shutdowntrueに設定し、条件変数に信号を送ります。あなたがメッセージを押すと同期させる必要があり

void Server::handleReceivedMessages() 
{ 
while (1) 
{ 
    std::unique_lock<std::mutex> lck(_mtxReceivedMessages); 
    while (!shutdown && _queRcvMessages.size() == 0) cv.wait(lck); // As long as there are 0 messages in the queue 
    if (shutdown) return; 
} 
} 
+0

問題は、ターミナルのXボタンを押してユーザーを閉じると、何らかの理由でデストラクタが呼び出されず、プログラムがクラッシュするということです。 –

+0

あなたのバグは他の場所です。私が言ったように、*すべて*にクリーンシャットダウンを設計する必要があります。 –

関連する問題