Ниже приведено краткое доказательство концепции, которую я собрал из более крупного проекта, над которым я работаю. В проекте есть рабочий поток, созданный с использованием CreateThread
, который отслеживает изменения в каталоге. У меня есть определенный код очистки, который должен запускаться как закрытие дескрипторов и освобождение памяти.
Приложение не запускается как фоновый процесс или служба. Он запускается через командную строку и выполняется до тех пор, пока пользователь не закроет командное окно или не нажмет Ctrl-C
.
Есть ли лучший способ сделать это? Я попытался использовать atexit
, но это, очевидно, не вызывается, когда процесс завершается.
Обратите внимание, что я использую C, а не C ++ и не использую MFC, AFX или любой другой API, кроме Windows API. Основываясь на комментариях, я предполагаю, что другая часть этого - как правильно завершить приложение в многопоточной среде? Это нормально, или я должен позвонить ExitProcess
в thread_func
?
UPDATE:
Я обновил комментарий Люка ниже относительно установки флага, чтобы указать, что приложение завершается. Я также изменил его для использования 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;
}