Bezpiecznie zamykanie wątku

0

Witam.

Jak bezpiecznie zamknąć wątek?

Bo chyba nie TerminateThread - to podobno niebezpiecznie.

Przypuśćmy mam taką sytuacje:

Mam kilka wątków, które wykonują czynności [obsługa zdarzeń, locki, alokowanie pamięci, czynności trwające kilkadziesiąt sekund(np pętla sleep), oczekiwanie na półączenie z klientem (funkcja accept) ].

Nagle muszę przerwać wszystko, żeby wznowić to za jakiś czas (kilka minut).

Mógłbym użyc tu TerminateThread, ale co jak wątek się przerwie na locku?, co jak zaalokuje pamięć - przecieŻ jej nie zwolni, co jak będzie obsługiwać zdarzenie i nie przekaże systemowi zdarzeń, że już skonczył je używać?

No to wymyśliłem sobie, że każdy wątek będzie miał swoją zmienną, i każdy wątek będzie sprawdzał czy nie jest tam true, jak true to wtedy przerywa wątek (funkcja przerywająca wszystkie wątki by ustawiała true każdemu wątkowi żeby się zamknął)

No i jest problem.

Wątki korzystają z dziesiątek funkcji, które mają pętle ze sleepami itd, czekającą nawet kilkadziesiąt sekund - czyli bym musiał w dziesiątkach funkcji, w każdej pętli sprawdzać id wątku i sprawdzać czy zmienna zamykająca ten wątek jest równa true i wtedy ewentualnie rzucić wyjątek, który przerwie wszystkie funkcje... bezsens.

A poza tym, co jak wątek aktualnie korzysta z accept (funkcja czekająca, aż klient się połączy)
Wtedy w ogóle nie będzie możliwości sprawdzić zmiennej zamykające wątek...

Nie mam pojęcia co zrobić.

Proszę o pomoc, z góry dziękuje.

0

Zamiast Sleep używaj SleepEx z parametrem bAlertable=TRUE, sprawdzając czy funkcja zwróciła WAIT_IO_COMPLETION. Jeżeli zwróci tą stałą, to masz pierwszy sygnał (w wątku) do wyjścia ze wszystkich pętli. By zakończyć taki uśpiony wątek (poza standardowymi metodami ze zmienną lub event'em) wywołujesz funkcję QueueUserAPC podając jej uchwyt do wątku i adres pustej funkcji o prototypie PAPCFUNC.
Jeżeli masz gdzieś w wątkach funkcje WaitForSingleObject, WaitForMultipleObjects, MsgWaitForMultipleObjects to podobnie jak ze Sleep - użyj wersji Ex z odpowiednią flagą, by wątek był w stanie allertable podczas uśpienia.

Blokującą funkcją accept najprościej przerwać zamykając soket, lub nawiązując połączenia z innego wątku, po uprzednim ustawieniu flagi "wyłącz się".

Jeżeli wątek który aktualnie jest właścicielem (np. muteksu) zakończy żywot bez zwalniania muteksu, to funkcja oczekująca na ten mutex w innym wątku zwróci WAIT_ABANDONED i automatycznie zmieni właściciela mutexu.

0

Hohoho, dzięki wielkie.

A co do wyjścia z pętli to jak ją opuścić jeżeli jest kilka pętli zagnieżdżonych bez używania np:

bool breakLoop;

?

Może rzuceniem wyjątku przez throw?

0

ja "goto" używam przy bardzo zagniezdzonych petlach..

0
sapero napisał(a)

Blokującą funkcją accept najprościej przerwać zamykając soket, lub nawiązując połączenia z innego wątku, po uprzednim ustawieniu flagi "wyłącz się"

przy okazji - jezeli uzyjesz mniej lub bardziej globalnych flag do nakazywania watkom zmiany ich zachowania, to warto rozwazyc czy nie nalezy tym flagom nadac 'volatile'

1 użytkowników online, w tym zalogowanych: 0, gości: 1