Thema: Delphi Einem Thread Zeit geben

Einzelnen Beitrag anzeigen

Olli
(Gast)

n/a Beiträge
 
#9

Re: Einem Thread Zeit geben

  Alt 9. Jun 2006, 11:44
Zitat von xaromz:
Mach ich inzwischen. Der Originalcode ist durch Faulheit entstanden (eine Listenänderung kommt nicht so oft vor, deshalb ist normalerweise ah kein Thread aktiv).
Gut!

Zitat von xaromz:
Mit dem Zugriff auf die Listenelemente hab ich kein Problem, der ist geschützt.
Wie? Ansonsten gälte u.U. das hier: Das was guste geschrieben hat, ist einerseits nicht so dumm, andererseits naiv. Das Problem ist, daß man jedem Listenelement eine eigene Critical Section mitgeben müßte. Tut man's nicht, hat man sogleich den Sinn des Thread ad absurdum geführt ...

Zitat von xaromz:
Danke, ich spreche fließend x86er assembler .
Ich hoffe nicht, weil ich mich dann quasi blamiert habe - da steht ja aus Assemblersicht nur Nonsens, auch wenn die Opcodes selber existieren

Zitat von xaromz:
Wie gesagt, der Zugriff auf die Elemente ist gesichert.
Wie, wie, wie? Wenn du ein Ausschlußobjekt für eine riesige Liste hast, kann nur einer lesen oder schreiben, also serialisierst du den Zugriff wieder künstlich.

Zitat von xaromz:
Siehe oben.
Hat leider mit dem geschützten Zugriff nichts zu tun, wenn du auf die "Gleichzeitigkeit" der Threads wertlegst.

Zitat von xaromz:
Das wird so nicht funktionieren. Die Änderung der Liste wird nämlich währenddessen angezeigt. In der Liste befinden sich Objekte mit den Dateinamen von Mediendateien (mp3, avi, mpeg...). Die Namen stehen in einer Listbox. Im Hintergrund werden diese Objekte mit Metadaten der Medien gefüllt (Bitrate, Videoauflösung, Spurenanzahl, ID3-Tags...), und gegebenenfalls die Anzeige in der Listbox verändert.
Da ich eine bestimmte Reihenfolge in der Liste habe und die Liste auch immer vollstängig sein muss, funktioniert das so leider nicht.
Dann stellt sich mir aber die Frage, warum du die Liste immer neu befüllst anstatt den jeweiligen Eintrag zu ergänzen (oder zu ersetzen). Eine doppelt verlinkte Liste ermöglicht dir das einfache Einfügen oder Entfernen von Listenelementen ohne gleich die komplette Liste neu befüllen zu müssen ...

Zitat von xaromz:
Wenn ich das Programm beende, während der Thread noch läuft, erhält dieser keine Chance, sich sauber zu beenden. Deshalb möchte ich eben beim Beenden des Programms den Hauptthread kurz schlafen legen, damit der Arbeitsthread auf ein Flag reagieren und sich beenden kann.
und wie wacht der Hauptthread dann wieder von alleine auf? Dann wird dein Programm nämlich vermutlich zwangsbeendigt.

Meines Erachtens ist deine Denk- und Herangehensweise zu naiv. Du könntest dir eine Menge Arbeit sparen, wenn jede Liste ein Ausschlußobjekt hat (könnte ein Byte- oder DWORD-Wert sein), der immer nur über die Interlocked-Funktionen bearbeitet wird. Dieses Ausschlußobjekt ist kein echtes Objekt sondern ein Referenzzähler. Da jedes Objekt nun nur noch ein Pointer auf einen Speicherbereich ist, übergibst du dieses an einen Thread nachdem der Aufrufer den Referenzzähler um 1 erhöht hat. Danach kann der Thread erstmal machen was er will, außer daß er davon ausgehen muß, daß die Daten jederzeit von einem anderen Thread gelesen werden können - die Integrität muß also garantiert sein (z.B. kritischer Abschnitt für jede der zu schreibenden Informationen ...). Wenn der (Arbeits-)Thread mit der Abarbeitung fertig ist, legt er sich erstmal selber schlafen (suspend) nachdem er den Referenzzähler um 1 reduziert hat. Dadurch ist er immer an einer wohldefinierten Stelle eingeschlafen. Will der Dispatcher-Thread nun dem Arbeits-Thread sagen, daß er wieder was machen soll, wird der Pointer (globale Variable o.ä.) zum Listeneintrag atomisch ausgetauscht und der Arbeits-Thread wieder aufgeweckt, womit die Schleife im Arbeits-Thread ihre Arbeit weiterführt. Damit ist zwar ein extra Thread (der Dispatcher) nötig, aber die Anzahl der Arbeits-Threads kann ohne Mühe variiert werden. Außerdem mußt du nur einen Listeneintrag in der Listbox aktualisieren, nicht die komplette Liste.

Zitat von xaromz:
Ich möchte also Windows sagen, dass jetzt erst mal alle anderen Threads ausgeführt werden sollen (meinetwegen auch ein bestimmter Thread, ich hab das Handle ja), und danach wieder der Hauptthread.
Du kannst aber nur Windows sagen, daß dein aktueller Thread seine Rechenzeit abgibt ... an wen, läßt sich der Scheduler von einem Usermode-Programm sicher nicht vorschreiben ... selbst im Kernelmode geht das nur beschränkt.
  Mit Zitat antworten Zitat