Autor Beitrag
GuaAck
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 306
Erhaltene Danke: 29

Windows 8.1
Delphi 7 Pers.
BeitragVerfasst: Do 15.05.14 22:47 
Liebe Experten,

ich möchte eine umfangreiche Rechenaufgabe auf viele Kerne einer CPU verteilen, also mache ich mehrere Threads.

Bsp.: Ich suche die "schönste" (wie auch immer) Zahl im Bereich 1... 1 Million, also teile ich das in 1000er-Pakete. Ich starte Thread 1 für 1..1000, dann Thread 2 für 1001..2000 usw.

Jetzt kommt das Problem: Wenn alle Threads beschäftigt sind, dann muss der organisierede Thread warten. Nehme ich "waitfor" auf Event, Mutex, Semaphore. Mein Problem liegt in den Rechen-Threads: Der sieht ja etwa so aus:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
Procedure Excecute;
REPEAT
  Suche_schönste_Zahl_im Bereich;
  Setze Event/Mutex/Semaphore;
  suspend;
UNTIL ewig; {klar, Terminated usw. wird abgefragt}
END;


NUN: Was passiert, wenn zwischen "Setze Event/Mutex/Semaphore" und "suspend" ein Threadwechsel erfolgt? Der übergeordnete organisierende Thread erwacht aus seinem "waitfor", findet aber keinen Thread, der "suspended" ist. Selbst wenn ich eine eigene Variable einrichte und abfrage, dann würde ja das Resume ins Leere laufen.

Klar, mir fallen work-arounds ein, aber das muss doch vom Ansatz her besser gehen. In den reichlich verfügbaren Texten im Internet habe ich nichts zu dieser Frage finden können.

Aber vielleicht ist ja auch mein Ansatz vollkommen falsch???? Evtl. besser den Thread terminieren und jeweils neu starten??? Oder gibt es außer Event, Mutex, Semaphore bessere Alternativen???
Im Prinzip sind solche Aufgagen heute bei Multi-Core-Anwendungen für aktuelle Prozessoren doch dauernd zu lösen. Somit hoffe ich auf Tipps und Links auf entsprechende Seiten.

Beste Grüße GuaAck

Moderiert von user profile iconMartok: Delphi-Tags hinzugefügt
Sinspin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1182
Erhaltene Danke: 96

Win7
DXE2 Prof, Lazarus
BeitragVerfasst: Fr 16.05.14 00:56 
Warum beendest du den knusper Thread nicht einfach wenn er fertig ist? Warum suspendieren und Speicher/Systemressourcen blockieren? Zudem ist suspended in neueren Version von Delphi als veraltet markiert.
Vor dem Beenden sendest du dann ein Event das dem Hauptthread sagt das wieder Platz auf der CPU ist und weitere arbeit vergeben werden kann.
Oder du verwendest TCriticalSection um eine globale Bariable hoch oder runter zu zählen. Die wird dann im Haupttread überwacht und neue abeit erzeugt. Mit TCriticalSection ist es auch möglich die Ergebnisse in eine globale Liste zu schreiben ohne das ein anderer Thread in die Quere kommen kann. Allerdings kann das zum Flaschenhals werden wenn die Arbeitsthreads zu schnell fertig sind. Da sie ihre Daten ja nur einer nach dem anderen schreiben können.

_________________
Solange keine Zeile Code geschrieben ist, läuft ein Programm immer fehlerfrei.
Ich teste nicht, weil ich Angst habe Fehler zu finden.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 18715
Erhaltene Danke: 1623

W10 x64 (Chrome, IE11)
Delphi 10.2 Ent, Oxygene, C# (VS 2015), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Fr 16.05.14 07:33 
Das Stichwort ist Threadpool, da gibt es auch schon fertige Implementierungen, eine umfangreiche z.B. drüben in der Delphipraxis. Ich muss los, deshalb kann ich grad nicht mehr schreiben.
Martok
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Moderator
Beiträge: 3655
Erhaltene Danke: 594

Win XP x86, Win 8.1 x64
Lazarus Snapshot; Delphi 7,2007,XE; PHP (PHPEdit,PhpStorm); JS; Java(Eclipse)
BeitragVerfasst: Fr 16.05.14 18:53 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Das Stichwort ist Threadpool, da gibt es auch schon fertige Implementierungen, eine umfangreiche z.B. drüben in der Delphipraxis. Ich muss los, deshalb kann ich grad nicht mehr schreiben.
Ich arbeite z.B. sehr gern mit der mittlerweile eingestellten AsyncCall (da ist das gradezu trivial, da du eine lokale bzw anonyme Prozedur für die Berechnung nehmen kannst), die OmniThreadLibrary taucht auch immer mal wieder auf (für die sind aber meine Delphis zu alt).

_________________
"The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."