2010-11-19 6 views
4

私のアプリケーションは、それが次のアルゴリズムが実行されるCreateThreadを使用して作成されたトレッドを閉じる準備ができている:スレッドが5割り当てられた秒以内に閉じることに失敗した場合適切なクリーンアップスレッドは閉じに失敗した場合 - C++

_bCloseRequested = TRUE; 
dwMsThen = ::GetTickCount(); 

do 
{ 
    ::GetExitCodeThread(m_hThread, &dwExitCode); 
    dwMsNow = ::GetTickCount(); 
} 
while((dwExitCode == STILL_ACTIVE) && ((dwMsNow - dwMsThen) < 50000UL)); 

を、スレッドのハンドルを閉じるか、開いたままにしておきますか?ありがとう。

答えて

6

まず、スレッドがこのように終了するのを待つ必要はありません。待っているすべての使用可能なCPU時間を使い果たすことになります。これは、スレッドの終了に時間がかかるという短所もあります。

使用代わりに、このような何か:言っ

WaitForSingleObject(m_hThread, 50000); 

:あなたがスレッドを実行したままにするか否かのスレッドが何をするかに依存します。あなたの主なアプリが何か他のことをやっても、実行することができますか?あなたはスレッドを殺すと、開いたままになる重要なもの(ファイル、接続、データベース、...)を開いていますか?スレッドを強制終了するか、実行中のままにするかを決定する前に、このすべてを考慮する必要があります。

+0

このスレッドは、シリアルポートから非同期入力を受信するために使用されます。ただし、スレッドはシリアルポートを開くためのリソースを所有していません。スレッドが所有する唯一のリソースは、受信したデータを処理するために管理する循環バッファです。スレッドが閉じられると、そのバッファも必要なくなります。 –

0

どちらもありません。スレッドをきれいに終了しないようにして、それに簡単に参加する必要があります。他のすべてはちょうどハックです。

+0

スレッドが_bClos​​eRequested変数自体をチェックしていない場合は、それが問題の本当の原因です。ユーザーが開始したアクションを長く実行しても、そのケースを正しく処理するためにユーザーがシャットダウンを要求したかどうかを確認する必要があります。 –

+0

@Harper Shelby:はい、スレッドは '_bClos​​eRequested'を監視し、安全にクリーンアップしてシャットダウンできるようにします。 –

+1

個人的には、boolや他の変数をチェックして、いつシャットダウンするかを判断するのが悪い設計だと思います。イベントドリブンシステムでは、ほとんどのスレッドは、(条件変数、ファイル記述子などの)待ち時間の大半を費やしているはずです...それらをシャットダウンするには、それらを起動し、終了するように明示的に指示する必要があります彼らが終了する時であることに気づくために彼らに頼っている)...さらに、変数のチェックは、99.999999パーセントの時間で終了するため、プログラムが終了するまで高価になります。 – dicroce

2

スレッドハンドルを待つだけです。時間がかかりすぎる場合は、アプリをタイムアウトさせて終了させ、スレッドが終了しないようにするバグを修正してください。

static const DWORD TIMEOUT_VALUE(50000); 

if (WaitforSingleObject(m_hThread, TIMEOUT_VALUE) != WAIT_OBJECT_0)) 
{ 
    // thread did not exit in time, log and exit process 
} 
1

これにはいくつかのアプローチがあります。

最初のアプローチは、私が理想的なアプローチと考えているものです。それは決してスレッドを終了させないことです。この理由は、複数ありますが、ここではいくつかのbiggiesです:あなたのスレッドは、同期オブジェクトを所有している、彼らは

  • RAIIオブジェクトは
  • をクリーンアップする機会を得ることはありません解放されない場合が

    1. メモリは
    2. を解放されません割り当てられたあなたはcertianカーネルコールの途中である場合は、したがって、このアプローチで行く

    あなたのアプリケーション全体をホースができ、あなたはスレッドがシャットダウンされていない理由を特定しますその問題を解決してください。問題が深刻になることがあります。デッドロック、競合状態などが見つかることがあります。静的分析は、これらの問題を見つけるのに役立ちます。

    理想的なアプローチは、常に欲しいものです。そして、これを行うには、スピンロックを使用しないことをお勧めします。代わりに、タイムアウトのスレッドハンドルのWait()。スピンすることで、リソースを無駄にし、あなたが待っているスレッドからタイムスライスを盗みます。

    実世界では、実動コードでは、他のすべてが失敗した場合の代替手段が必要です。最初に、複数のメソッドを試して、スレッドをシャットダウンするようにしてください。完全な最後の手段としてすべてが失敗した場合は、スレッドを強制終了します。しかし、ゾンビスレッドを殺す危険性があるので、これをやったら、アプリケーション全体を再起動する必要があります。スレッドを強制終了すると、プロセスを非決定的な状態に置くことができます。だからやり直してください。エラーメッセージを記録し、アプリケーションを終了してから、もう一度やり直してください。

  • +0

    詳細なフィードバックをありがとうございます。それは間違いなく心に留めている仕事です。私の主な専門分野は組み込みの世界にあるので、私は笑わなければならない。そこでは、あなたがそれを「紡績」と呼ぶのは一般的なことです。あなたは良い点を持っています。他の人が推奨している 'WaitForSingleObject'を実装しようとしています。すべての詳細+1。 –

    +0

    @ジム:私は埋め込みのために深刻なコーディングをしたことは一度もありませんでしたが、私は回転が非常に一般的であることに驚いています。特に制限されたリソースでは、16 GBのラムを搭載したデュアルCPUマシンよりも、回転しないことがさらに重要になると私は期待しています。 : –

    +0

    これは実際にシステムがどのように構成されているかによって異なります。イベントドリブンOSを使用する場合は、できるだけポーリングを避ける必要があります。しかし、私がやったことのほとんどはあまり複雑ではありません。通常、メインループを回転させるだけで、フラグがセットされるのを見ています。 –

    関連する問題