idepozapalki Temat założony przez niniejszego użytkownika |
[WinApi] Zamykanie uruchomionego dodatkowego wątku. » 2021-10-26 19:29:34 Krótki opis sytuacji. W aplikacji okienkowej uruchamiam dodatkowy wątek: std::thread worker( worker_thread, i ); worker.detach();
i - numer struktury (StructureInVector) zawierającej informacje o przetwarzanym pliku detach - żeby aplikacja okienkowa nie "zwisła" Tak wygląda uruchamiana funkcja worker_thread: void worker_thread( int i ) { SetTimer( hWnd, IDT_PROGRESS_TIMER, 100,( TIMERPROC ) NULL ); StructureInVector.at( i ).onProcessing = true; std::lock_guard < std::mutex > lock( mut ); ControlModul * process = new ControlModul( StructureInVector.at( i ), hTextBox, hTab, hWnd ); StructureInVector.at( i ).onProcessing = false; StructureInVector.at( i ).iStatus = true; delete process; }
Problem pojawia się podczas analizy bardzo dużych plików tekstowych -> okolice 1GB Użytkownik może w trakcie analizy rozmyślić się i chcieć zakończyć aplikacje okienkową w sposób standardowy czyli krzyżykiem. Właściwie powód nie jest istotny, kłopotem jest zamykanie aplikacji okienkowej gdy uruchomiony jest worker. Zamknięcie przetwarzającej aplikacji przy uruchomionym Visual Studio powoduje pojawienie się okienka: Microsoft Visual C++ Runtime Library z komunikatem Debug Error! Program: ..\bin\x64Debug\Analizator.exe abort()has been called (Press Retry to debug the application) Powodem jest oczywiście działanie pomocniczego wątku podczas gdy zamykane są okienka. W jaki sposób mogę to zrobić w "cywilizowany" sposób ? Dobrze byłoby też uruchomić destruktor obiektu process żeby posprzątał po sobie. |
|
pekfos |
» 2021-10-26 20:25:06 Nie powinno być dodatkowych wątków w momencie wyjścia z programu. Powinieneś zapewnić mechanizm dla ich czystego wyłączenia i zaczekać na ich wyłączenie, najlepiej wywołaniem join(). Sam sygnał wyłączenia możesz zrealizować np z użyciem std::atomic_bool. Wątek powinien okresowo sprawdzać wartość flagi w czasie swojej pracy i przerwać działanie jeśli jest ustawiona. |
|
idepozapalki Temat założony przez niniejszego użytkownika |
» 2021-10-26 21:19:00 Wiem, że poczekanie na wyłączenie wątku byłoby najbardziej humanitarne. Robiłem testy i przetwarzanie/analiza dużego pliku dochodziła jednak do godziny. Jeżeli użytkownik pomyliłby się i wrzucił nie ten plik który zamierzał to czekałaby go godzinna przerwa. Dodatkowo aplikacja pracuje w jednej instancji (względy praktyczne) więc to czekanie też nie jest najlepszym rozwiązaniem.
Zastanawiałem się nad wykorzystaniem zdarzenia WM_CLOSE
Może to byłoby dobre rozwiązanie ?
http://www.bo-yang.net/2017/11/19/cpp-kill-detached-thread |
|
pekfos |
» 2021-10-26 21:24:28 Nie chodzi o to by czekać aż wątek zakończy swoją godzinną pracę, tylko żeby tą pracę skrócić. Po prostu przestań czytać plik kiedy jest ustawiona flaga, że użytkownik anulował zadanie. |
|
idepozapalki Temat założony przez niniejszego użytkownika |
» 2021-10-26 22:33:08 Plik nie jest czytany w trakcie działania wątku. Wczytuję go na początku do stringstreamu w RAMie i później w takcie pracy używam tylko jego. Wiem, że w początkowej fazie może nie jest to najlepsze rozwiązanie, ale przy pracy z dużymi plikami to się sprawdza. Wszystko mam w Ramie i zwykłe ubicie wątku podejrzewam, że zostawi ten cały śmietnik w Ramie. |
|
pekfos |
» 2021-10-27 16:37:47 Póki ta godzina jest spędzona w twoim kodzie, możesz tam dodać warunek by przerwać działanie wcześniej. Piszę to samo już trzeci raz, naprawdę nie wiem jak to napisać jaśniej. |
|
idepozapalki Temat założony przez niniejszego użytkownika |
» 2021-10-27 20:31:28 Dziękuję, dotarło do mnie, że mam przejrzeć główne pętlę w programie i dodać tam sprawdzanie zmiennej globalnej sygnalizującej wyjście z okienek. W zdarzeniu WM_CLOSE będzie ona przestawiana. Przy okazji chciałem zapytać czy w Visual Studio jest jakiś mechanizm w trakcie debugowania do podglądnięcia ile jest stworzonych obiektów i do ich obserwacji? |
|
DejaVu |
» 2021-10-27 21:42:43 Za pomocą debuggera możesz zobaczyć zarówno uruchomione wątki, jak również stan zmiennych, które są widoczne z miejsca, w którym się zatrzymasz (np. za pomocą breakpointa). Każdy przyzwoity debugger to potrafi. |
|
« 1 » 2 |