以下は、私が取り組んでいる大規模なプロジェクトから集めた概念の簡単な証明です。プロジェクトには、変更をディレクトリで監視するCreateThread
を使用して作成されたワーカースレッドがあります。私はクローズハンドルのように実行し、いくつかのメモリを解放する必要がある特定のクリーンアップコードを持っています。マルチスレッドWindowsコンソールアプリケーションを正しく終了する
アプリケーションは、バックグラウンドプロセスまたはサービスとして実行されません。これはコマンドラインで実行され、ユーザがコマンドウィンドウを閉じるか、またはCtrl-C
を押すまで実行されます。
これを行うより良い方法はありますか?私はatexit
を使ってみましたが、プロセスが強制終了されたときには呼び出されていないようです。
私はC++ではなくCを使用していますが、MFC、AFX、またはWindows API以外のAPIを使用していないことに注意してください。コメントに基づいて、この別の部分は、マルチスレッド環境でアプリケーションを正しく終了させる方法です。これでいいですか?をthread_func
に電話する必要がありますか?
更新日: 私は、アプリケーションが終了していることを示すフラグを設定するためのLukeのコメントを更新しました。また、atexit
を使用して、直接呼び出すのではなくクリーンアップ関数を呼び出すように変更しました。一般的な意味で
#include <stdio.h>
#include <windows.h>
HANDLE thread_handle = INVALID_HANDLE_VALUE;
BOOL time_to_quit = FALSE;
DWORD WINAPI thread_func(LPVOID lpvd)
{
fwprintf(stdout, L"thread running...\n");
while (!time_to_quit)
{
/* do stuff */
Sleep(10);
}
return 0;
}
void cleanup()
{
/* clean up code here that needs to be run at exit */
fwprintf(stdout, L"cleaning up...\n");
CloseHandle(thread_handle);
}
BOOL WINAPI console_handler(DWORD event)
{
time_to_quit = TRUE;
return FALSE;
}
int wmain(int argc, wchar_t* argv[])
{
DWORD thread_id = 0;
thread_handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)thread_func, NULL, 0, &thread_id);
if (thread_handle != NULL)
{
atexit(cleanup);
fwprintf(stdout, L"thread created...\n");
SetConsoleCtrlHandler((PHANDLER_ROUTINE)console_handler, TRUE);
WaitForSingleObject(thread_handle, INFINITE);
}
return 0;
}
信号()またはリターンからを使用する場合がありますことができ'main'](http://stackoverflow.com/questions/9402254/how-do-you-run-a-function-on-exit-in-c/9402278#9402278)。 'SetConsoleCtrlHandler'はあなたのために働いていませんか? –
CreateThreadは、INVALID_HANDLE_VALUEではなく、失敗した場合にNULLを返します。 –
ああ、NULL感謝。 @セス、問題の一部は、アプリケーションを終了する方法です。私は全面的に 'cleanup'を呼び出すことを望まないでしょう。私はいくつかの説明で質問を更新しました。 – Casey