2016-05-05 4 views
5

内のスレッドは、私がこのようなものがあります:どのように正常にシャットダウンC

DWORD WINAPI test(LPVOID lpParam) { 
    while (1) { 
     /*DO STUFF*/ 
    } 
} 

int main() { 
    ... 
    hThread = CreateThread(NULL,0,test,NULL,0,&dwThreadId); 
    ... 
} 

をどのようにすることができます私はシャットダウンのTerminateThreadなしのスレッド()? 私の最初のアイデアは、グローバル変数(shouldshutdown = 0/1)を作成し、スレッドをシャットダウンするときにmain()に設定しました。その後、スレッドのExitThread()を呼び出します。したがって、私は推測する悪いスタイルのスレッドのwhileループでこの変数をチェックする必要があります。

+0

スレッドは返さなければならないことをスレッドがどのように知っていますか? – 2501

+0

シグナルハンドラを使用 – Charlestone

+0

@ 2501彼はdoesntです。それは問題です。私はループのチェックのようなものを実装する必要があります - 私はこれを避けたいです。 – Kntlii

答えて

11

スレッドが停止する必要があるかどうかを確認できるイベントが発生しました。たとえば、(エラー処理なし):

DWORD WINAPI test(LPVOID lpParam) 
{ 
    HANDLE hEvent = (HANDLE)lpParam 

    while (WaitForSingleObject(hEvent, 0) == WAIT_TIMEOUT) 
    { 
     /*DO STUFF*/ 
    } 
} 

int main() { 
    hEvent = CreateEvent(NULL, TRUE, FALSE, NULL) 
    hThread = CreateThread(NULL,0,test,(LPVOID)hEvent,0,&dwThreadId); 
    // Do 
    // Stuff 
    // Tell the thread to exit 
    SetEvent(hEvent) 

    // Wait for the thread to exit 
    WaitForSingleObject(hThread, INFINITE); 
} 

一般的なパターンは、監視可能な何らかの種類のアラート可能なオブジェクトをスレッドに与えることです。この場合、手動リセットイベントを使用しました。 whileループは、イベントが通知されているかどうかをチェックし、イベントが通知されていないかどうかをチェックします。それが通知されると、WaitForSingleObjectWAIT_OBJECT_0を返し、ループは終了し、スレッド関数から脱落します。

主な機能では、イベントを通知してからスレッドが終了するのを待っているだけです。

+0

不透明なライブラリでスレッドがCPUバインドされていると動作しません。 –

+1

@MartinJamesしかし、この場合には、とにかく多くのことをする必要はありません。 –

+0

[インターロックされた変数アクセス関数](https://msdn.microsoft.com/en-us)を使用する方がはるかに効率的です/library/windows/desktop/ms684122(v=vs.85).aspx)をイベントオブジェクトよりも優先します。 –

0

メインスレッドとワーカースレッド間でメッセージを送信する必要がある場合(たとえば、実行する作業がキューに配置されているなど)、最も単純なオプションは、単純にワーカースレッドにメッセージを渡すことですループ。

PostThreadMessage APIを使用して、実行するタスクがあるメッセージにWM_APPメッセージを投稿し、スレッドを終了するときにメッセージをWM_QUITに送信できます。これにより、独自のスレッドセーフシグナリングメカニズムを構築する手間が省けます。

ワーカースレッドがCOMオブジェクトをインスタンス化している場合は、最初の呼び出しをCoInitializeに追加し、そのスレッドが有効なSTAである必要があります。

+0

COM **を使用するスレッドは、必ずCoInitialize/Ex()を呼び出す必要があります。しかし、スレッドはCOMを使用してメッセージループを作成する必要はありません。 –

+0

@RemyLebeauが修正されました。ありがとう。 –

0

スレッドをシャットダウンする場合は、次の2つのオプションがあります。 1.スレッドを強制終了します(TerminateThreadを使用)。 2.スレッドにシャットダウンするように依頼します(これはスレッドが機能するためには協力しなければなりません)。

2番目のオプションを選択すると、その方法の選択肢がいくつかあります。 1つの選択肢は、グローバルフラグを使用してスレッドを終了するように指示することです(私はあなたがなぜそれが悪いスタイルだと思うかわかりません)。最良の選択はおそらくあなたのスレッドが何をしているかに依存します。

関連する問題