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?