![]() |
Klasse klasse mit mehreren Threads synchronisieren
Liste der Anhänge anzeigen (Anzahl: 1)
Hiho.
Ich schreibe gerade mein ach so beliebtes LoggedOn2 um. Nun habe ich folgendes vor: Schema der Klasse als ![]()
Folgendermassen:
Einzig ueber die Sache mit dem Index bin ich mir noch nicht im Klaren ... also bitte keine Kommentare dazu! Also, meine Frage: Wie koennte ich die einzelnen Teile sinnvoll und synchronisiert so verbinden, dass ich nicht den Vorteil der Multithreading verliere, dass mir aber andererseits nicht die Bytes hin und wieder nur so um die Ohren fliegen, weil's ne Exception gab?! Bitte um qualifizierte Antworten. Grosse Teile sind bereits implementiert ... nur fliegt mir hin und wieder ne Exception um die Ohren ... offensichtlich wegen Sync-Problemen. [edit=sakura]Bild wegen Größe entfernt - Download-Link ist ja vorhanden. Mfg, sakura[/edit] [edit=Daniel B]Titel korrigiert. Mfg, Daniel B[/edit] |
Re: Klasse klasse mit mehreren Threads syncen ... oh Hülfe
Ich denke mal, die Exception tritt im Moment auf, wenn die Listen up-to-date gebracht werden. Ich würde vorschlagen, dass Du an der Stelle entweder auf Interfaces wechselst - der Aufwand ist hier u.U. jedoch nicht gerechtfertig, oder Du lässt Deine Threads durch eine CriticalSection laufen, wenn Sie die Liste verändern wollen. Ersteres lässt alle Sorgen über, evtl. in der Zwischenzeit freigegeben Objekte verfliegen.
Vielleicht habe ich Dich aber auch nicht richtig verstanden :roll: ...:cat:... |
Re: Klasse klasse mit mehreren Threads syncen ... oh Hülfe
Dieser Post wurde wegen grammatischer und ausdrücklicher :mrgreen: Stilblüten gelä ... ü ... öscht .. *verdammteenglischetastaturhat*
|
Re: Klasse klasse mit mehreren Threads syncen ... oh Hülfe
Ich meinte weniger die Downloadgröße - als die Bildgröße - die sprengt bei einigen Besuchern die Grenzen - ja, es gibt hier noch User mit 800-Pixel Auflösung :roll:
Was ist mit dem Rest :?: :mrgreen: ...:cat:... |
Re: Klasse klasse mit mehreren Threads syncen ... oh Hülfe
Meist lande ich in LeaveCriticalSection irgendwo in der NTDLL oder der System32 ... wenn das Programm beendet wird und dann der Debugger zuckt.
Nachtrag: Wozu gibt es Scrollbars? Wenn sich so jemand das auf seinem Homerechner anschaut, hat der das gleiche Prob :mrgreen: |
Re: Klasse klasse mit mehreren Threads syncen ... oh Hülfe
Zitat:
...:cat:... |
Re: Klasse klasse mit mehreren Threads syncen ... oh Hülfe
Zitat:
...:cat:... |
Re: Klasse klasse mit mehreren Threads syncen ... oh Hülfe
LOL. Problem bei Mutexes, die sind leider echte und mit Namen bestueckte Kernelobjekte. Deshalb kann ich sie nicht gebrauchen. Denk mal an, was passiert, wenn ich mehrere Instanzen der Anwendung starte ;)
IMHO Critical Sections oder die InterLocked-Funcs ... was anderes kommt wahrscheinlich nicht wirklich in Frage. Noch ander Ideen? Haste vielleicht mal selbst nen eigenen Sync-Mechanismus gebastelt? |
Re: Klasse klasse mit mehreren Threads syncen ... oh Hülfe
Zitat:
Wenn Du trotzdem Mutexes nutzen willst, kannst Du an den Namen die Instance-ID des Programmes ranhängen und schon ist das Problem von MaxInt laufenden Instanzen gelöst ;-) ...:cat:... |
Re: Klasse klasse mit mehreren Threads syncen ... oh Hülfe
Hast du jemals deine Instanzenhandles ausgewertet? Die sind alle die Lade-Adresse des Hauptmodules im eigenen Speicherbereich. Meist $400000 :D (seit Win32 erstmals rauskam ist dies so)
Wenn dann muesste es schon die Thread-ID oder so sein. Aber Mutexe sind ja grade deshalb langsam, weil es Kernelobjekte sind. Es muss der Thread ja in den Kernel-Mode jumpen und wieder zurueck. Das kostet mindestens 800 Zyklen. Nachtrag: Rueck mal ein paar konzeptionelle Details zu deinem Ansatz raus :mrgreen: |
Re: Klasse klasse mit mehreren Threads syncen ... oh Hülfe
Mit geht es momentan um eine globale CS - da ist der Ansatz von Hagen super:
![]() ...:cat:... |
Re: Klasse klasse mit mehreren Threads synchronisieren
Nutze InterlockedXXXX() funktionen und Zwischengespeicherte Ergebnissmengen. Der TreeView wiederum nutzt Polling um per InterlockedXX() Variablen die Zwischengespeicherten Mengen in seinen Context zu kopieren. Soweit in kurzform, ich glaube aber ich muß es klarer verdeutlichen.
Der TreeView zeigt einen bestimmten Status an. Dazu werden dahinterliedende Datenmengen benötigt. Der UpdaterThread hat ein eigenes vollständiges Duplikat dieser Daten, aktualisiert alle Änderungen und erzeugt die Daten die dann im TreeView angezeigt werden. Nun inkementiert er einen Zähler per InterlockedIncrement(FMustDisplay). Der UpdaterThread aktualisiert die Daten wenn FMustUpdate = 0 ist und setzt diesen Wert auf 1 während er Updated. Ist er fertig mit dem Update dann erhöht er diesen Wert auf 2. Der MainThread.TTreeView pollt FMustDisplay und wenn der Wert 2 vorliegt beginnt er diese Daten einzuarbeiten. Er erhöht den Wert auf 3 und wenn er fertig ist setzt er ihn auf 0 zurück. Da ein Zugriff auf einen an 4 Bytegrenzen ausgerichteten Integer als Atomarer Zugriff stattfindet, und atomare Operationen der CPU threadsafe sind, lässt sich das sogar ohne InterlockedXXX() Funktionen erledigen. Solange FMustDisplay <= 2 ist kann der UpdaterThread erneut seine Daten ändern. Da der TreeView im Idle-Modus, also immer FMustDisplay pollt wenn keine Messages im Queue sind, wird es sogar möglich das der UpdaterThread mehrmals sehr schnell hintereinander die daten aktualisert. Der TreeView zeigt aber immer nur den letzten Zustand an, also leicht Zeitversetzt. Gruß Hagen |
Re: Klasse klasse mit mehreren Threads synchronisieren
Danke erstmal an sakura. Ich werde es aber erstmal noch nicht nehmen.
Ich bleibe mal bei den CS der API. Also, hab mir das jetzt mal so ausgedacht:
Code:
- Die Klasse hält (privat) die ID und das Handle zum DispatcherThread
- Dadurch kann mit PostThreadMessage() der Dispatcher kommandiert werden - Der Disptacher kümmert sich intern um die Geschäfte mit allen anderen Threads, inklusive deren Steuerung, Beendigung etc pp. - Der Dispatcher reicht einen Pointer zu der Liste mit den Rechnern an jeden Thread weiter, der was tun soll (GUI, MAC, Workers). So wissen diese ab dem Start, wo sie gucken können, wenn sie in der Liste stöbern müssen. Dieser Pointer muß von den Threads als Readonly behandelt werden. - Update der Daten kommt sowieso nur von den Workers! Diese müssen ein Update anmelden, indem sie per PostMessage den Pointer zu den Daten für die eingeloggten User sowie den Index des Records zurückgeben. - Der Dispatcher macht das Update, sobald keiner der Threads mehr gerade diesen Record liest! Will heißen, NUR der Dispatcher bestimmt, wann er die Records tauscht ... weshalb es NICHT ERLAUBT ist, daß ein anderer Thread (zB Hauptthread) die Adresse des Records zwischenspeichert! - Der vorige Punkt sollte klarer werden, sobald man weiß, daß der GUI- Thread nur per PostThreadMessage() vom Dispatcher den Befehl für ein Update erhalten kann. - Critical Sections werden gebraucht für: + Update der Liste mit den Rechnern im Netzwerk + Schreiben/Lesen der Daten welcher User wo eingeloggt ist. Ich hoffe, daß ich dadurch, daß die Verwaltung der anderen Threads nur noch dem Dispatcher obliegt, es schaffen kann die Konflikte auszuräumen. Unter anderem sollte es dann möglich sein auf einige (vielleicht sogar mehr als geplant) Critical Sections zu verzichten, da die Abarbeitung ja allein durch die Benutzung von Message-Loops in den Threads einger- maßen serialisiert worden sein sollte. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:03 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz