AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Berechnungs-Threads die lesend auf Dynamische Arrays zugreif
Thema durchsuchen
Ansicht
Themen-Optionen

Berechnungs-Threads die lesend auf Dynamische Arrays zugreif

Ein Thema von tobias_sdr · begonnen am 12. Mai 2009 · letzter Beitrag vom 15. Mai 2009
Antwort Antwort
tobias_sdr

Registriert seit: 7. Apr 2009
3 Beiträge
 
#1

Berechnungs-Threads die lesend auf Dynamische Arrays zugreif

  Alt 12. Mai 2009, 21:39
Hallo alle miteinander,

ich habe folgendes Problem und benötige zur Lösung eure Hilfe.

Ich fülle einen TCollection mit "Jobs"; sprich jedes Item der TCollection besitzt die Parameter, mit denen dann ein Thread seine Berechnungen durchführen soll. Sprich mein Hauptthread legt den Pool an und befüllt diesen auch. Gleichzeitig über WaitForSingleObject(aJobList.Semaphore, INFINITE) prüfen die anderen Threads, ob in dem Pool Jobs sind. Sind welche vorhanden, soll sich jeder einen nehmen und berechnen, solange bis der Pool leer ist. In dieser Zeit soll der Hauptthread nach Beendigung des Füllens auf die Abarbeitung der Jobs und die Beendigung der Berechnung warten. Die Threads sollen aktiv bleiben.

Die Threads greifen während ihrer Berechnung lesend auf eine gemeinsame Datenstrucktur aus Dynamischen Arrays zu, die nur von dem Hauptthread beschrieben wird nachdem der Pool leer ist und die Threads fertig sind. Ich habe hier im Forum gelesen, dass Dynamische Arrays zu Problemen führen können. Leider weiß ich nicht, wie ich das umgehen soll. Eine Syncronisierung jedes Zugriffes würde doch wahrscheinlich zur Verlangsamung des Programms führen, oder?


Woran kann das liegen?
  Mit Zitat antworten Zitat
Blup

Registriert seit: 7. Aug 2008
Ort: Brandenburg
1.477 Beiträge
 
Delphi 12 Athens
 
#2

Re: Berechnungs-Threads die lesend auf Dynamische Arrays zug

  Alt 14. Mai 2009, 08:57
Wenn nur lesend gleichzeitig auf das Array zugegriffen wird, dürfte das nicht zu Problemen führen.
Allerdings würde ich es vermeiden den Referenzzähler von Strings, Arrays oder Interfaces dabei zu verändern.
Wenn solche Werte als Parameter übergeben werden, dann nach Möglichkeit immer als const-Parameter.
Das aber eher aus Gründen der Geschwindigkeit, insbesondere wenn mehrere Prozessoren auf den selben Speicher zugreifen.

Ansonsten schau mal in der Delphi-Hilfe nach diesen Stichworten:
TThread
TCriticalSection
TMultiReadExclusiveWriteSynchronizer

Insbesondere Zugriffe auf den Pool sollten z.B. durch TCriticalSection abgesichert sein.
  Mit Zitat antworten Zitat
tobias_sdr

Registriert seit: 7. Apr 2009
3 Beiträge
 
#3

Re: Berechnungs-Threads die lesend auf Dynamische Arrays zug

  Alt 14. Mai 2009, 10:15
Hallo und erst mal Danke für die Antwort,

die Dyn.-Array sind als "Global" über eine Unit in die Threads-Unit eingebunden. Der Zugriff auf den Pool erfolgt über Semapore und das Lesen und Schreiben über Mutex. Ich dachte auch, dass der Fehler da liegt. Wenn ich aber die Berechnungseinheit der Threads in eine Exception kapsele wird der Fehler abgefangen. Ich habe aber nur lesenden Zugriff in den Berechnungsthreads. Mein Hauptthread vergrößert die Dyn-Array nach jeden Berechnungsdurchlauf um das Ergebnis.

Zu deinem Vorschlag
Zitat:
Allerdings würde ich es vermeiden den Referenzzähler von Strings, Arrays oder Interfaces dabei zu verändern.
Leider weiß ich nicht, wie ich das machen soll?

Danke nochmal für deine Hilfe
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.475 Beiträge
 
Delphi 12 Athens
 
#4

Re: Berechnungs-Threads die lesend auf Dynamische Arrays zug

  Alt 14. Mai 2009, 10:49
Zitat von tobias_sdr:
Ich habe aber nur lesenden Zugriff in den Berechnungsthreads. Mein Hauptthread vergrößert die Dyn-Array nach jeden Berechnungsdurchlauf um das Ergebnis.
Ich denke, da sitzt das Problem! DynArrays sind ja eigentlich nichts anderes als Pointer auf ein Array bestimmter Größe. Beim Vergrößern des DynArrays wird bei Bedarf neuer Speicherplatz an ganz anderer Stelle zugewiesen, das Array dorthin kopiert und der Pointer angepasst. Der alte Speicherplatz wird freigegeben und kann für andere Sachen verwendet werden. Wenn nun während einer Berechnung im Neben-Thread der Haupt-Thread das DynArray verschiebt, arbeitet der Neben-Thread auf dem falschen Speicherbereich.

Um es mal so auszudrücken: "Nur-Lesen" bei mehreren Threads gilt immer auch für den Haupt-Thread. Sobald einer schreibt sollte man synchronisieren. Es mag zwar Fälle geben, wo das unnötig ist, aber wer garantiert denn, daß das bei der nächsten Programmänderung bzw. beim nächsten Delphi- oder Windows-Update so bleibt?
Uwe Raabe
  Mit Zitat antworten Zitat
tobias_sdr

Registriert seit: 7. Apr 2009
3 Beiträge
 
#5

Re: Berechnungs-Threads die lesend auf Dynamische Arrays zug

  Alt 14. Mai 2009, 11:02
Danke, so hab ich das auch Verstanden.

Mein Haupthread wartet über
WaitForSingleObject(ajobList.fEventJob.Handle,5000); auf die Abarbeitung des Jobpools und mit

WaitForSingleObject(MyThreadSemaphore.fEventThread.Handle,5000); auf die Beendigung der Threads erst danach werden die Ergebnisse vom Haupthread geschrieben.

Kann ich das Problem durch Nutzung von TCollection anstelle von Dyn.-Arrays umgehen?

Danke für eure Hilfe.
  Mit Zitat antworten Zitat
pertzschc

Registriert seit: 29. Jul 2005
Ort: Leipzig
309 Beiträge
 
Delphi 12 Athens
 
#6

Re: Berechnungs-Threads die lesend auf Dynamische Arrays zug

  Alt 14. Mai 2009, 11:22
Schau auch mal folgende Diskussion an: WorkerThread
Gruß,
Christoph
  Mit Zitat antworten Zitat
Blup

Registriert seit: 7. Aug 2008
Ort: Brandenburg
1.477 Beiträge
 
Delphi 12 Athens
 
#7

Re: Berechnungs-Threads die lesend auf Dynamische Arrays zug

  Alt 15. Mai 2009, 10:36
Zitat von tobias_sdr:
Der Zugriff auf den Pool erfolgt über Semapore und das Lesen und Schreiben über Mutex. Ich dachte auch, dass der Fehler da liegt.
Ich würde die Semapore durch TCriticalSection ersetzen und wirklich jeden lesenden und schreibenden Zugriff auf den Pool darüber nur innerhalb von Enter und Leave.

WaitForSingleObject(ajobList.fEventJob.Handle,5000 );
Ist sichergestellt, das wirklich alle Jobs bereits durch einen Thread bearbeitet werden/wurden?

WaitForSingleObject(MyThreadSemaphore.fEventThread .Handle,5000);
Ist sichergestellt, das wirklich der letzte Thread beendet wurde?

Zitat von tobias_sdr:
Wenn ich aber die Berechnungseinheit der Threads in eine Exception kapsele wird der Fehler abgefangen.
Es tritt also tatsächlich ein Fehler auf, wie lautet die Fehlermeldung? Zugriffsverletzung?
Ich würde den Fehler auf jeden Fall bei den oben genannten Punkten suchen.

Zitat von tobias_sdr:
Zu deinem Vorschlag
Zitat:
Allerdings würde ich es vermeiden den Referenzzähler von Strings, Arrays oder Interfaces dabei zu verändern.
Leider weiß ich nicht, wie ich das machen soll?
Zitat:
Wenn solche Werte als Parameter übergeben werden, dann nach Möglichkeit immer als const-Parameter.
Das kann aber kein Ursache für die Exception sein.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:00 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz