Multithreading - Wie mit Threads richtig arbeiten ?



  • Schönen guten Abend liebe Community,

    ich stehe momentan etwas auf dem Schlauch und benötigte einen kleinen Denkanstoß.
    Ich möchte eine Textdatei Zeilenweise lesen und mittels Threads diese Zeilen bearbeiten.
    Es sollen maximal nur 5 Thread gestartet werden, dann soll auf die Threads gewartet werden.
    Soweit eigentlich ganz simple.
    Um aber nicht unnötig Zeit zu verschwenden, möchte ich nun das wenn 1 Thread beendet ist ein neuer wieder gestartet wird damit permanent 5 Threads laufen.

    Offen und ehrlich gesagt habe ich aber absolut keine Ahnung wie ich das bewerkstelligen kann.

    Mein Momentaner Ansatz:

    while(fgets(strCurrentLine, MAX, f)) {
    
    		hThread[iCounterThreads] = _beginthreadex(NULL, 0, CheckData, (void*)strCurrentLine, 0, NULL);
    		Sleep(1000);
    
    		iCounterThreads++;
    
    		if(iCounterThreads == 5) {
    			WaitForMultipleObjects(iCounterThreads, &hThread, TRUE, INFINITE);
    
    			for(i = 0; i < 5; i++) 
    				CloseHandle((HANDLE)hThread[i]);
    
    		}
    	}
    

    Vielen dank schonmal für kommende Antworten.


  • Mod

    1. Solltest Du dafür sorgen, dass der Thread auch seine Daten behält. Wenn Du einen Buffer verwendest, dann ist der Thread noch nicht fertig und fgets zerstört den Inhalt. Du benötigst für jeden Thread einen Buffer.

    2. Zum Algorithmus Bau eine Verwaltung auf.
    Pseudocode

    While (AnyLinesLeft)
    {
      if (AllThreadsAreRunning)
      {
        WaitForOneThread
        RemoveFinishedTheadFromList
      }
      AddThreadToList
    }
    WaitForAllThreads
    

    Am besten führst Du einen Array der Threeds handles und fügst immer den fertigen Thread aus dem Array aus.

    3. Könntest Du Dir mal Thread Pools ansehen.



  • Martin Richter schrieb:

    1. Solltest Du dafür sorgen, dass der Thread auch seine Daten behält. Wenn Du einen Buffer verwendest, dann ist der Thread noch nicht fertig und fgets zerstört den Inhalt. Du benötigst für jeden Thread einen Buffer.

    2. Zum Algorithmus Bau eine Verwaltung auf.
    Pseudocode

    While (AnyLinesLeft)
    {
      if (AllThreadsAreRunning)
      {
        WaitForOneThread
        RemoveFinishedTheadFromList
      }
      AddThreadToList
    }
    WaitForAllThreads
    

    Am besten führst Du einen Array der Threeds handles und fügst immer den fertigen Thread aus dem Array aus.

    3. Könntest Du Dir mal Thread Pools ansehen.

    Hallo Martin,
    vielen Dank für deine Antwort.

    1. Das habe ich gedacht mit einem Zeiger auf Zeiger zu lösen.

    2. Danke für diesen Denkanstoß. Habe das jetzt versucht so umzusetzen:

    unsigned int hThread[100] = {0};
    	int iCurrentThreads = 0;
    	int iThreads = 25;
    	int iThreadcounter = 0;
    
    	while(fgets(strCurrentLine, MAX, f)) {
    
    		if(iCurrentThreads == iThreads) {
    
    			WaitForMultipleObjects(iCurrentThreads, (HANDLE)&hThread, FALSE, INFINITE);
    
    			for(x = 0; x < iThreads; x++) {
    				GetExitCodeThread((HANDLE)hThread[x], &dwExitCode);
    
    				if(dwExitCode != STILL_ACTIVE) {
    					CloseHandle((HANDLE)hThread[x]);
    					hThread[x] = 0;
    					iCurrentThreads--;
    					iThreadcounter--;
    				}
    			}
    
    		}
    
    		if(iCurrentThreads != iThreads) {
    			while(hThread[iThreadcounter] != 0)
    				iThreadcounter++;
    
    			iCurrentThreads++;
    			hThread[iThreadcounter] = _beginthreadex(NULL, 0, CheckData, (void*)strCurrentLine, 0, NULL);
    		}
        }
    

    Das funktioniert auch ganz gut wenn ich oben iThreads mit 4 deklariere.
    Gebe ich 5 an dann geht es schon los, es werden bis zu 400 Threads erstellt und dann stürzt das Programm ab.
    Bin das ganze jetzt schon mit dem Debugger durchgegangen, aber konnte keinen Fehler finden.

    Will es so einfach wie möglich halten und auf Threadpools erstmal verzichten.


  • Mod

    Auf den ersten Blick: Du verwendest in jedem Fall iThreadCounter falsch.

    In der while loop geht er out of bounds.
    Was ist wen thread 0 endet?...


Anmelden zum Antworten