Jak zabić wątek główny?

0

W momencie uruchomienia programu mamy 1 wątek główny. Czy jest jakaś możliwość by zabić wątek główny po naciśnięciu klawisza 'Z' i tym samym wyjść z programu, czyli jak np. wykonuje się jakaś pętla for z tysiącem indeksów i w tej pętli for mamy na końcu Sleep(5000) to żeby taki ciąg instrukcji też się od razu przerwał a nie że dopiero jak zakończy wykonywać kod to zareaguje na klawisz 'Z'? Pewien pomysł jaki mi przyszedl to stworzenie wątku nr 2 w wątku głównym, ale o ile klawisz 'Z' mi wykrywa to nie umiem teraz zabić wątku głównego. Ma ktoś jakiś pomysł? Dodam tyle, że odpada przeniesienie wszystkich funkcji z wątku głównego do tego drugiego. Na początku błąd popełniłem, ale teraz przenosić wszystko to masakra, zresztą to winapi to nawet nie wiem jak.

0
  1. Jaki system? Jakie wątki (biblioteka)?
  2. Jaki to problem wywołać exit(0) po prostu? Albo użyć kill()?
0

@Shalom: winapi - strzelam, że to windows.

@rero: pod win proces kończy się dopiero, jak skończą się wszystkie jego wątki - tak na wszelki wypadek to piszę, bo zakończysz główny wątek, a zapomnisz o zakończeniu drugiego i będziesz się dziwił, że proces się nie zakończył, a nie reaguje na nic.

0

A jednak postaraj sie i przerzuć tą pętle do dodatkowego wątku roboczego. A zarządzanie wątkami pozostaw wątkowi głównemu.

0

Nie da rady exit(0) bo to wątek podrzędny wyłapuje naciśnięcie klawisza 'Z'. I jak wyłapie to chciałbym by przerwał wykonywanie kodu wątku nadrzędnego. W grach zwykle tak jest że jest akcja, naciskasz ESC i ci się menu ort! albo z gry wychodzi. Ja tak nie umiem zrobić. Jak nie dam wątku podrzędnego to mi dopiero reaguje na klawisz 'Z' po tym jak zakończy cały kod funkcji, pętle itp. I stąd pomysł stworzenia wątku podrzędnego który wyłapuje klawisz 'Z', tylko teraz po wyłapaniu trzeba by powiedzieć jakoś wątkowi nadrzędnemu żeby wyszedł z najbardziej zagnieżdzonej pętli, funkcji do

While(GetMessage(..,...,...))
{
TranslateMessage;
DispatchMessage;
}

tej pętli nie mogę przerzucić, bo to tak tylko napisałem, że to pętla jest, ale to nie jest pętla tylko wszystko - cały szkielet aplikacji, funkcja główna winMain oraz jej nieodłączna funkcja sterująca aplikacją w której piszemy komunikaty reakcji na zdarzenia: WM_COMMAND, BN_CLICK itp.

0

Działa exit(0). A przed exitem(0) trzeba zwalniać pamięć, zabijac okna wszystkie jak sugerują tutoriale czy wystarczy exit(0) i ono już o to zadba?

0

Ladniej byłoby zarejestrować funkcję sprzątającą za pomocą atexit() jakiegoś ;)
Większość zasobów zostanie zwolniona, tak samo jakbyś zwyczajnie program ubił, ale mogą być jakieś problemy z otwartymi plikami, pamięcią wspólną, potokami i tym podobnymi zabawkami, które niekoniecznie są związane z konkretnym procesem.

0
Shalom napisał(a)

mogą być jakieś problemy z otwartymi plikami, pamięcią wspólną, potokami i tym podobnymi zabawkami, które niekoniecznie są związane z konkretnym procesem.

Pod Windows (NT) z tym problemu nie będzie, wszystko to obiekty udostępniane aplikacjom poprzez uchwyty i odpowiednie API, do obiektów są zliczone referencje, uchwyty zapisywane w tablicach uchwytów procesów itd. Za rzeczy związane z USER/GDI odpowiada podsystem Windows (głównie csrss + win32k.sys), pilnuje wszystkiego, co jest dla niego specyficzne. W momencie zamknięcia procesu (niezależnie od powodu) zapisane w strukturach procesu uchwyty są zwalniane (spada licznik referencji), bez dodatkowych odwołań obiekt jest niszczony, zgodnie ze swoim typem (z punktu widzenia C++ wręcz klasą, bo typy są wyposażone w metody wirtualne) jest poddawany odpowiedniej destrukcji. Zwykłe aplikacje niezbyt mają możliwość stworzyć coś, co po nich pozostanie.

Podsumowując - NT to nie 9x, nie gubi zasobów jeżeli jakiś program przed zamknięciem ich nie zwolni.

0

@up to znaczy ze windows nie dysponuje czymś takim jak np. pamięć wspólna, czy semafory, które nie są przypisane do procesu jako takiego, tylko do pewnego klucza (jak ma to miejsce w unixach)?

0

Obiekty nie są bezpośrednio przypisane do procesu, co najwyżej uchwyty do nich. O ile pamiętam to zależnie od flag mogą istnieć i bez istniejących referencji (gdy licznik spadnie do zera), ale generalnie z punktu widzenia aplikacji użytkownika to mało jest rzeczy, które istniałyby z zerową ilością odwołań.

Szczerze mówiąc nie pamiętam jak to w uniksach wygląda nawet...

http://en.wikipedia.org/wiki/Object_Manager_(Windows) - powinno jaśniej i prawdziwiej opisywać sytuacje niż ja, po całym dniu nad WinDBG przy debugowaniu VM jestem padnięty totalnie.

0
while(1)
   if(GetAsyncKeyState(VK_RETURN)) break;
SendMessage(::hWnd,WM_DESTROY,0,0);

W wątku drugim (podrzędnym obok nadrzednego który sam się tworzy w momencie uruchomienia aplikacji) mam taki powyżej kod. Niestety wadą jest zajętość 100% całego rdzenia. Powyższy kod gwarantuje mi to że obojętnie kiedy nacisnę Enter to aplikacja zareaguje mi na klawisz nawet jak wątek nadrzedny wykonuje jakiś kod. Czy ktoś umiałby coś pokombinować by był jakiś sposób, żeby aplikacja reagowała na Entera bez zajmowania 100% rdzenia? Wyjściem jest
while(GetMessage(&message,NULL,0,0)>0)
{
if(GetAsyncKeyState(VK_RETURN)) break;
TranslateMessage(&message);
DispatchMessage(&message);
}
SendMessage(::hWnd,WM_DESTROY,0,0);

ale to nie działa bo wątek reaguje na własną kolejkę komunikatów a nie na kolejkę komunikatów wątku nadrzędnego. Potrzebuje jeszcze czegoś innego.
0

Czyli trzeba by programowi powiedzieć że ta pętla to niech pobiera komunikaty z wątku nadrzędnego.

0

mimo że jest napisana w wątku podrzędnym i by działało bez zajętości 100% procesora. To moja 1 aplikacja tak duża toteż nauczyłem się że najlepi to robić tak, że od razu tworzyć wątki poboczne i tam dawać kody do programu a niech wątek nadrzedny zarządza Enterami, zabijaniem aplikacji itp. No ale teraz nie bede zmieniał wszystkiego bo z miesiąc siedzieć jeszcze bym musiał to trza wykombinowac coś dla aktualnej implementacji i tutaj jest pole do inwencji twórczej, do nowatorstwa.

0

Mi sie coś takiego udało wykombinować:

   while(1)
   {
      if(GetAsyncKeyState(VK_RETURN)) break;
	  Sleep(500);
   }

Zajętość procka od 0 do 2%. A poziom reakcji na entera akceptowalny i niezauważalny że jest interwał czasowy. Ktoś wymyśliłby coś lepszego?:)

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