Как правильно остановить поток, который использует критическую секцию?

Подскажите пожалуйста, как правильно остановить поток, который использует CriticalSection, в C++ используя WinAPI. Функция потока у меня выглядит примерно так:

DWORD WINAPI threadFunc(LPVOID param) {
    EnterCriticalSection(&cs);
    ...
    LeaveCriticalSection(&cs);
    return 0;
}

И в любой момент времени, во время действия потоков, я останавливаю любой из n потоков при помощи функции TerminateThread, которая не освобождает CriticalSection из-за чего, когда очередь доходит до этого потока, то на строчке LeaveCriticalSection возникает вот такая ошибка:

Вызвано исключение по адресу 0x76EBF463 (ntdll.dll) в MultiThreadApp.exe: 0xC0000005: нарушение прав доступа при записи по адресу 0x0528F948.

Так как правильно остановить поток, который использует критическую секцию?

EDIT:

Решил попробовать использовать оболочку для CRITICAL_SECTION, вот пример кода:

#include <stdio.h>
#include <iostream>
#include <windows.h>

const int THREADS_COUNT = 10;
CRITICAL_SECTION cs;
HANDLE threads[THREADS_COUNT];
clock_t start;

class LockCriticalSection {
public:
    LockCriticalSection(CRITICAL_SECTION* cs) : cs(cs) { }
    void Lock() { EnterCriticalSection(cs); }
    ~LockCriticalSection() { LeaveCriticalSection(cs); }
private:
    CRITICAL_SECTION* cs;
};

DWORD WINAPI threadFunc(LPVOID param) {
    LockCriticalSection test(&cs);
    test.Lock();

    printf("THREAD - %d before sleep\n", (int)param);
    Sleep(2000);
    printf("THREAD - %d after sleep\n", (int)param);

    return 0;
}

int main() {
    InitializeCriticalSection(&cs);

    start = clock();
    for (int i = 0; i < THREADS_COUNT; ++i)
        threads[i] = CreateThread(NULL, 0, threadFunc, (LPVOID)i, 0, NULL);

    Sleep(2000);

    printf("Terminate Thread\n");
    TerminateThread(threads[4], 0);

    WaitForMultipleObjects(THREADS_COUNT, threads, TRUE, INFINITE);

    clock_t end = clock() - start;

    char resultTime[128];
    sprintf_s(resultTime, "Время выполнения программы: %f", end / (double)CLOCKS_PER_SEC);
    printf("%s", resultTime);

    for (int i = 0; i < THREADS_COUNT; ++i)
        CloseHandle(threads[i]);

    DeleteCriticalSection(&cs);
    return 0;
}

Но он так же возвращает ошибку при LeaveCriticalSection


Ответы (1 шт):

Автор решения: user7860670

Правильный способ остановки потока только один - дождаться завершения его работы и закрыть дескриптор. TerminateThread использовать категорически нельзя.

→ Ссылка