[ANSI C][WINAPI] wątki pod <windows.h>

0

Cześć,
napisałem taki programik który dzieli plik wejściowy na części i każdą z tych części obrabia oddzielny wątek. Cały program jest w ANSI C, a obsługę wątków implementuje biblioteką <windows.h>, używam Visual C++.

Wszystko zaimplementowane w sposób by nie było sekcji krytycznych w programie. Każdy z wątków używa oddzielnych danych danych i nie ma możliwości by wpływały na siebie.
Otóż moim problemem jest niezrozumiały deadlock, lub też nieumiejętność odpowiedniego zaradzenia mu.

Oto poniżej przedstawiam swoją funkcję która odpala i kontroluje wszystkie wątki.

void start(int beben1, int beben2, int beben3, int poz1, int poz2, int poz3, char* nazwa_pliku_zr, char* nazwa_pliku_wyj, int ile_r)
{
	pWatku tab_param[5];
	DWORD dwwynik;
	int i;
	ile_rdzeni=ile_r;
	for (i=1;i<=ile_rdzeni;i++)
	{
		if (i==1)
		{
			tab_param[1].beben1=beben1;
			tab_param[1].beben2=beben2;
			tab_param[1].beben3=beben3;
			tab_param[1].id_start=0;
			tab_param[1].id_tab=1;
			tab_param[1].poz1=poz1;
			tab_param[1].poz2=poz2;
			tab_param[1].poz3=poz3;
			tab_param[1].tekst1=tab_czesci_szyfrow[1];
			tab_watkow[1] = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)start_watku,&tab_param[1],0,&tab_id_watkow[1]);
			if (tab_watkow[1]==NULL) // tworzenie wątku z parametrem ustalonym wyżej i sprawdzenie czy wszystko jest ok
			{
				printf("Blad! nie udalo sie utworzyc watku 1\n");
				exit(1);
			}
		}
		else
		{
			tab_param[i].beben1=beben1;
			tab_param[i].beben2=beben2;
			tab_param[i].beben3=beben3;
			tab_param[i].id_start=strlen(tab_czesci_szyfrow[i-1])+1;
			tab_param[i].id_tab=i;
			tab_param[i].poz1=poz1;
			tab_param[i].poz2=poz2;
			tab_param[i].poz3=poz3;
			tab_param[i].tekst1=tab_czesci_szyfrow[i];
			tab_watkow[i] = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)start_watku,&tab_param[i],0,&tab_id_watkow[i]);
			if (tab_watkow[i]==NULL)
			{
				printf("Blad! nie udalo sie utworzyc watku %d\n",i);
				exit(2);
			}
		}
	}
	
	dwwynik = WaitForMultipleObjects(ile_rdzeni,tab_watkow,TRUE,INFINITE); // powinno czekac na zakonczenie sie wszystkich watkow, a na debugu zaraz //idzie do przodu nie czekajac wcale na wykonanie watkow

	  switch(dwwynik) // zinterpretowanie wyniku czekania na obiekty, caly czas wychodzi Waiting failed
      {
        // hThr[0] was signaled
        case WAIT_OBJECT_0 + 0:
            // TODO: Perform tasks required by this event
            wprintf(L"First event was signaled...\n");
            break;
 
        // hThr[1] was signaled
        case WAIT_OBJECT_0 + 1:
            // TODO: Perform tasks required by this event
            wprintf(L"Second event was signaled...\n");
            break;
 
            // hThr[2] was signaled
        case WAIT_OBJECT_0 + 2:
            // TODO: Perform tasks required by this event
           wprintf(L"Third event was signaled...\n");
            break;
 
            // ...
 
            // Time out
        case WAIT_TIMEOUT:
            wprintf(L"The waiting is timed out...\n");
            break;
 
        // Return value is invalid.
        default:
            wprintf(L"Waiting failed, error %d...\n", GetLastError());
            ExitProcess(0);
      }     
 

	for (i=1;i<=ile_rdzeni;i++)
		CloseHandle(tab_watkow[i]);
} 

Wszystko fajnie, tworzę tablicę z handlami i z idikami wątków, a funkcja WaitForMultiplieObjects nie chce czekać na zakończenie wątków tylko idzie dalej. Po uruchomieniu cały czas wyskakuje jako rezultat tej funkcji Waiting failed.

Oto kod funkcji która ma być wykorzystywana w każdym watku

 DWORD WINAPI start_watku(LPVOID arg)
{
	char we[27],w1[27],w2[27],w3[27],odw[27];

	pWatku p = *((pWatku*)arg);
	tab_we(we);
	wczytaj_beben(w1,p.beben1);
	wczytaj_beben(w2,p.beben2);
	wczytaj_beben(w3,p.beben3);
	wczytaj_beben(odw,7);
	przesun_ilosc_pozycji(p.id_start,w1,w2,w3);
	tab_czesci_zaszyfr[p.id_tab] = zaszyfruj(p.tekst1,p.poz1,p.poz2,p.poz3,we,w1,w2,w3,odw);
	//ExitThread(GetThreadId(tab_watkow[p.id_tab]));
	//ExitThread(tab_id_watkow[p.id_tab]);
	return 0;
	
}

Próbowałem kończyć wątek każdym z zakomentowanych funkcji, ale nie było żadnej różnicy. Przy debugu sprawdzałem i wątki działają poprawnie, tzn że wykonują swoją pracę tylko nie potrafią się zakończyć.

Programowanie wielowątkowe używając windows.h jest dla mnie całkiem nowe i do końca nie umiem uzywać tych narzędzi, czy ktoś może mi poradzić gdzie robię błąd?

0

Po uruchomieniu cały czas wyskakuje jako rezultat tej funkcji Waiting failed.

A co zwraca GetLastError?

0

zwraca wartość 6 czyli według strony poniżej niepoprawny uchwyt.

http://help.netop.com/support/errorcodes/win32_error_codes.htm

Nie wiem czemu niepoprawny uchwyt, bo podaje przecież tablicę ze wszystkimi handlami. Tablica ta jest zdefiniowana globalnie.

Sposób wywołania WaitForMultiplieObjects:

  WaitForMultipleObjects(ile_rdzeni,tab_watkow,TRUE,INFINITE);
0
if (i==1)
                {
                        tab_param[1].beben1=beben1; 
//...

Nie powinno być

tab_param[0].beben1=beben1; 
// oraz zamiast  - tab_param[i]
// tab_param[i - 1]...  ??
1

Nie wiem czemu niepoprawny uchwyt, bo podaje przecież tablicę ze wszystkimi handlami.

Tyle że pierwszy element tej tablicy nie jest ustawiony, ponieważ (nie wiedzieć czemu) indeksujesz od jednego zamiast od zera:

for (i = 1;i <= ile_rdzeni; i++)
{
	...
	tab_watkow[i] = CreateThread(...);
	...
}

dwwynik = WaitForMultipleObjects(ile_rdzeni,tab_watkow,TRUE,INFINITE); 
0

Specjalnie zastosowałem taką indeksację by była spójna z całą resztą indeksów używanych w programie. Zmienię indeksacje w tablicy uchwytów i idików od 0 i napiszę jaki będzie tego rezultat.

0

Specjalnie zastosowałem taką indeksację by była spójna z całą resztą indeksów używanych w programie.

No to ulala..

0

poprawiłem indeksację i wszystko śmiga jak należy:)

wielkie dzięki pozdro!

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