Einzelnen Beitrag anzeigen

alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#2

Re: Probleme mit Threads und Aufgaben-Pool

  Alt 17. Mai 2005, 20:16
Falls Du D6 benutzt, vergiss Synchronize, das klappt nicht.
Weiterhin solltest Du den Datenaustausch mit Threads irgendwie mit CriticalSections sichern. Anstatt direkt das Feld 'FTodo' zu setzen (ist doch nicht OOP, Mensch), schreib Dir eine Get- und eine Set-Methode im Thread. Den Zugriff auf das Feld fToDo kapselst du mit einer Critical Section.
So ist sichergestellt, das sich lese- und schreiboperationen nicht in die Quere kommen.

Obwohl das bei Dir eigentlich nicht passieren dürfte, da de NewJob Methode im Kontext des Hauptthreads ausgeführt wird...

Wenn ich mir das recht überlege, ist das aber nicht sonderlich cool, wie Du das machst. Ich würde die Todo-Liste erstmal als TThreadList implementieren, weil eben viele Threads darauf zugreifen. Das sollten sie auch gleichzeitig können. Ergo:
Delphi-Quellcode:
Type
  TJobList = Class
  Private
    fList : TThreadList;
  Public
    Function GetNextJob : TJob;
    Procedure AddJob (aJob : TJob);
    End;

Function TJobList.GetNextJob : TJob;
Var
  l :TList;

Begin
  l := fList.LockList;
  Try
    if l.Count = 0 Then
      Result := Nil
    else begin
      Result := l[l.count - 1];
      l.delete (l.count - 1);
      End;
  Finally
     fList.unlockList;
     End;
End;

Procedure TJobList.AddJob (aJob : TJob);
Var
  l :TList;

Begin
  l := fList.LockList;
  Try
    l.Add (aJob);
  Finally
    fList.unlockList;
    End;
End;
Nun kannst Du die Jobliste füllen (auch während die Threads ackern). Jeder Thread holt sich dann, wenn er fertig ist, den nächsten Job per GetNextJob und macht weiter. Liefert GetNextJob den Wert nil, macht der Thread eben nichts. Das ist ein kleines Problem, weil es nicht so leicht ist, einem Thread zu sagen, er soll nichts machen (also, auch keine CPU verbraten). Man muss ein Synchronisationsobjekt nehmen, ich würde es mit einer Semaphore versuchen. Jedesmal, wenn ein Job per AddJob in die Joblistee reingepackt wird, wird die Sempahore um eins erhöht.
Jeder Thread wartet, bis die Semaphore<>0 ist und holt sich einen Job aus der Liste. Nicht ausprobiert, sollte aber klappen.
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat