wielowątkowość a zakończenie programu

0

Szukałem po googlach, jakoś nie mogłem znaleźć
powiedzmy że mamy taki kod

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

using namespace std;

DWORD WINAPI FunkcjaWatku(PVOID pvParam)
{
  for (int i =  100 ; i < 110 ; i++){
    Sleep(1000);
    cout << i << endl;
  }

  return 0;
}

int main()
{
   int x = 6;
   DWORD IdWatku;

  CreateThread(NULL, 0, FunkcjaWatku, (PVOID)x, 0, &IdWatku);
  for (int i =  0 ; i < 10 ; i++){
    Sleep(500);
    cout << i << endl;
  }

  return 0;
}

więc main skończy się wcześniej niż FunkcjaWatku. Co w takim wypadku się stanie? Wątek będzie dalej działał mimo że działanie programu zostało zakończone? A może przerwie działanie? Próbowałem zobaczyć ewentualne zmiany na wykresie wydajności w menedżerze, ale jakoś nie jestem pewien co tam się dzieje.
Jak przed czymś takim się zabezpieczyć?
Czasami też wątki uruchamiają się w jednoczesnym momencie a czasami nie (wyświetla np 1027 a później robi dwa razy '\n') od czego to zależy?

I ogólnie, polecacie jakąś książkę/artykuł do poczytania na ten temat?

1

Wątek zostanie po prostu "ubity". Jeśli po wątku nie trzeba jakoś "sprzątać" (np. pozamykać jakieś uchwyty) to często się olewa, że jest to zwykłe ubijanie. Ale jakbyś chciał, by wątek zakończył się "prawidłowo" to użyj synchronizacji. Np.

volatile bool koniec = false; // czy wątek ma działać czy zakończyć działanie

DWORD WINAPI FunkcjaWatku(PVOID pvParam)
{
  while (!koniec) { // działamy dopóki zmienna "koniec" nie zostanie ustawiona na 'true'
     /* ... tutaj sobie cośtam robimy ... */
     /* ... warunek 'while (!koniec)' mus być co jakiś czas sprawdzany ... */
  } 
  return 0;
}
 
int main()
{
   /* ... */
 
   HANDLE hThread = CreateThread(NULL, 0, FunkcjaWatku, (PVOID)x, 0, &IdWatku); // <-- zapisujemy w zmiennej uchwyt do wątku
 
   /* ... tutaj sobie cośtam robimy ... */ 
   
   /* ... aż nadchodzi moment zakończenia programu */ 
   
   koniec = true; // oznajmiamy wątkowi aby przestał działać
   WaitForSingleObject(hThread, INFINITE); // czekamy, aż ten faktycznie się zakończy
 
   return 0;
}
1

Z chwilą zakończenia funkcji main, rozpoczyna się sprzątanie obiektów globalnych itp, po czym następuje zakończenie procesu. Z chwilą zakończenia procesu wszystkie wątki należące do procesu zostają natychmiastowo przerwane.

Rozwiązanie Twojego problemu:
http://cpp0x.pl/dokumentacja/standard-C++11/thread/join/1411

0

c:\program files (x86)\codeblocks\mingw\bin..\lib\gcc\mingw32\4.4.1........\include\winbase.h|2028|error: too few arguments to function 'DWORD WaitForSingleObject(void*, DWORD)'|

zapomniałeś o jednej zmiennej ;), ale to nie ważne, bo doczytam sobie w msdn dokładnie jak to działa :)</del> dzięki wielkie. A czy znasz odpowiedzi na te dwa pozostałe pytania?

  1. Dlaczego wątki uruchamiają się w jednoczesnym momencie a czasami nie (wyświetla np 1027 a później robi dwa razy '\n')?
  2. jaką książkę/artykuł do poczytania na ten temat?
2
  1. Powodem czegoś takiego jest to, że bardzo prawdopodobna jest taka sytuacja: najpierw zostanie wypisane i z jednego wątku, wątek zostaje zatrzymany i czas procesora dostanie następny wątek, który wypisze to i i endl, a następnie ten poprzedni znowu dostanie czas procka i wypisze endl.
    cout nie jest synchronizowany, wypisanie na ekranie nie jest operacją atomową, a konstrukcja cout << coś << coś_innego; to tak naprawdę dwukrotne wywołanie metody z klasy cout, a konkretnie operatora <<.

  2. Artykułów i tutoriali w tym temacie jest od groma. Zależy też z jakiej biblioteki do obsługi wątków korzystasz. google: c++ multithreading tutorial

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