wielowątkowość, kontrola wykonywania wątków

0

witam,

jestem w trakcie pisania wielowatkowego programu, z zalozenia sama idea nie jest dobra ma obrazowac tlyko wykonywnaia wielu watkow pomijamy tu problem waskeigo gardla jakim jest dostep do dysku

program listuje pliki z folderu i jego podfolderu

program znajduje katalog i tworzy watek ktory listuje pliki z niego, calkiem ciekawie to wyglada widac ze koeljnosc lsitowania katalogow nie jest zawsze taka sama

moje pytanie jest nastepujace, wiem ze nie jest to elegancko zrobione chodzi mi o funkcje uspienia sleep() na koncu, jak proboje inaczej to zrobic to nie chce dzialac, dodatkowo powiniem kozystac z funkcji _beginthreadex() ale nie moge uruchomic

bardzo bym byl wdzieczny za pomoc w ujeciu tego w bardziej elegancji sposob, identyfikacja watku i zaczekanie na wykonanie wszysktich

z gory dzieki

oto kod(uruchamiany na vs2008, windows vista premium):

#include <windows.h>
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <process.h>

const int BUFOR = 13333; // wielkosc bufora BUFOR
const int MAX_LIST_PLIK = 133333; // ograniczenie na ilosc listowanych plikow

struct folder { // struktura danych do ktorej zapiszemy dane wylistowanych plikow
       char sciezka[MAX_PATH+1]; // przechowamy to sciezke do pliku ktory listujemy - zmienna tekstowa typu char
	   char nazwa[MAX_PATH+1]; // przechowamy tu nazwe pliku listowanego - zmienna tekstowa typu char
	   int rozmiar; // przechowmay tu rozmiar pliku
};

typedef TCHAR* TCHARptr; // definicja typu char - unicode, dalej bedziemy uzywac funkcji strncpy wiec przy kompilacji z kodowaniem znakow unicode by sie posypalo
typedef folder* folder_ptr; // definicja typu wskaznika na struktura, powodem tej definicji sa klpoty przy deklaracji funkcji exportu dla biblioteki dll
 
using namespace std; // ustawienie przestrzeni nazw

//unsigned  __stdcall  listowanie_plikow(void * sciezkastart2);
DWORD listowanie_plikow(void * sciezkastart2);

int main () {

	HANDLE hWatki[1000];
	DWORD IdentWatku[1000];

    int liczbaFolderow = 0;
    int znacznikczytania = 0;
    int znacznikzapisania = 0;
    int ilePlikowZnaleziono = 0;
    int i = 0;
    int ilePlikowZnalezionoZnacznik = 0;
    
    TCHAR NazwaPliku[MAX_PATH+1];
    TCHAR glownyfolder[MAX_PATH+1];
	TCHAR folderznazwapliku[MAX_PATH+1];
    TCHAR bierzacyfolder[MAX_PATH+1];

	HANDLE hFile; // handler pliku
    WIN32_FIND_DATA kontener; // inicjowanie winapi find data, jest to tablica struktur w ktorej sa dane na temat kolejno znajdywanych plikow
    
    
    folder* allFilesFound; // wskaznik na strukture folder

    TCHAR filename[MAX_PATH] = "";
    TCHAR sciezka[MAX_PATH] = "";
    TCHAR filefound[MAX_PATH] = "";
	TCHAR filenamefound[MAX_PATH] = "";


	strncpy_s(NazwaPliku,"*",MAX_PATH); // dodanie * na poczatek glownej sciezki aby wylistowac wszsytkie pliki i foldery w katalogu glownym
    strncpy_s(glownyfolder,"C:/wamp/www/roi/",MAX_PATH); // skopiowanie przygotowanej sciezki do zmiennej glownego folderu

    
    // tworzymy tablice dynamiczna aby przechowac w niej drzewko katalogow
    folder* folderArray = new folder[BUFOR];
    strncpy_s(folderArray[znacznikzapisania].sciezka,glownyfolder,MAX_PATH);
    znacznikzapisania = znacznikzapisania + 1;
    allFilesFound = new folder[MAX_LIST_PLIK];

    // tworzymy liste drzewka katalogow i podkatalogow aby nastepnie wybrac z nich pliki
    while ((znacznikczytania < znacznikzapisania) && (znacznikzapisania < BUFOR)) {

        strncpy_s(folderznazwapliku,folderArray[znacznikczytania].sciezka,MAX_PATH);
        strncpy_s(bierzacyfolder,folderArray[znacznikczytania].sciezka,MAX_PATH);
        strncat_s(folderznazwapliku,"*",1);// dodanie * aby szukac dalej plikow wew folderu
        znacznikczytania = znacznikczytania + 1;

        hFile = FindFirstFile (folderznazwapliku, &kontener); // pocztek wyszukiwania plikow w drzewku
        if (hFile == INVALID_HANDLE_VALUE) {

        } else {

            while ( (FindNextFile(hFile, &kontener))) {

                if (((kontener.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY) && ((strcmp(kontener.cFileName,"..")))) {
                    if ((znacznikzapisania) >= BUFOR) {
                       // zatrzymuje szukanie folderow do wylistowania, poprzez przekroczenie ilosci folderow przewidzianego przez bufor
						cout << endl;
					}
                    else {
                       strncpy_s(folderArray[znacznikzapisania].sciezka,bierzacyfolder,MAX_PATH);
                       strncat_s(folderArray[znacznikzapisania].sciezka,kontener.cFileName,MAX_PATH);
                       strncat_s(folderArray[znacznikzapisania].sciezka,"\\",1);// dolacza na koniec backslasha "\"   

					   //listowanie_plikow(folderArray[znacznikzapisania].sciezka);


					   //hWatki[znacznikzapisania] = (HANDLE)_beginthreadex(NULL, 0, &listowanie_plikow, folderArray[znacznikzapisania].sciezka, 0, &IdentWatku[znacznikzapisania]);
					   hWatki[znacznikzapisania] = (HANDLE)CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)listowanie_plikow,folderArray[znacznikzapisania].sciezka,0,&IdentWatku[znacznikzapisania]);
					   
					   znacznikzapisania = znacznikzapisania + 1;
					   
                    }    
                } // if
             } // while
			 
             FindClose(hFile);
        }
    } // while (znacznikczytania != znacznikzapisania

// oczekiwanie na zakończenie wykonywania wątków
//WaitForMultipleObjects(znacznikzapisania, hWatki, TRUE, INFINITE );

Sleep (100000);

	return 0;
}
DWORD listowanie_plikow(void * sciezkastart2) {
//unsigned __stdcall listowanie_plikow(void * sciezkastart2) {
 

	TCHAR folderznazwapliku2[MAX_PATH+1];
    TCHAR bierzacyfolder2[MAX_PATH+1];

	HANDLE hFile2; // handler pliku
    WIN32_FIND_DATA kontener2; // inicjowanie winapi find data, jest to tablica struktur w ktorej sa dane na temat kolejno znajdywanych plikow
    
   
        strncpy_s(bierzacyfolder2,(char*)sciezkastart2,MAX_PATH);
        strncpy_s(folderznazwapliku2,(char*)sciezkastart2,MAX_PATH);
        strncat_s(folderznazwapliku2,"*",1);



        hFile2 = FindFirstFile (folderznazwapliku2, &kontener2);

        if (hFile2 == INVALID_HANDLE_VALUE) {
           // gdy podamy nieprawidlowa sciezke
			cout << sciezkastart2 << endl;
        } else {
		
             while (FindNextFile(hFile2, &kontener2)) {
              
                if ((kontener2.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY))
                {
                   // gdy znajdujemy folder to pomijamy go, byl on zapisany juz wczesniej wiec petla i tak wroci i wyslistuje pliki z tego foldera
                }
                else {

						cout << kontener2.cFileName << " | " << bierzacyfolder2 << endl;
                }

             }// while
             
             FindClose(hFile2);

        } // else

return 0;
}
0

Źle policzyłeś uruchomione wątki.

folder* folderArray = new folder[BUFOR];
strncpy_s(folderArray[znacznikzapisania].sciezka,glownyfolder,MAX_PATH);
znacznikzapisania = znacznikzapisania + 1;
Hmmm, tu też zwiększasz 'znacznikzapisania' ? Więc licz się, że będzie o jeden za dużo. W ogóle pomieszane to wszytsko jest strasznie.

W każdym razie żeby działało:

hWatki[znacznikzapisania - 1] = (HANDLE)CreateThread ...

WaitForMultipleObjects(znacznikzapisania - 1, hWatki, TRUE, INFINITE );

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