![]() |
AW: Ringpuffer Bibliothek veröffentlicht
Zitat:
Deshalb frage ich ja ob da schon sowas geplant ist und womöglich kommen wird, oder eher nicht. Zitat:
Zitat:
Ich dachte aber eher an eine Klasse die implizit threadsafe ist, also z.B. TRingbuffer<T> und TRingbuffer_Safe<T> So dass man die Klasse ohne Änderung beim Aufrufer 1:1 tauschen könnte. Das separate Enter/Exit hat natürlich auch seine Vorzüge, einer granulareren Steuerung, wenn man das in vielen unterschiedlichen Szenarien einsetzen würde. Eigentlich möchte ich nur die laufenden Basic's Push/Pop/Length usw. absichern, um bedenkenlos Lesen/Schreiben zu können, das wäre doch sehr gut integrierbar. Welche Vorteile hätte ich denn sonst noch von einem externen, separatem Enter/Exit ? Da sehe ich eher die Gefahr mal ein Enter/Exit zu vergessen. Das ist wohl wieder so eine Philosophie-Frage, wo es am Ende zwei Lager gibt :stupid: Oder gibt es da einen klaren, technischen Favoriten ? |
AW: Ringpuffer Bibliothek veröffentlicht
Historisch hab ich sonst ein Leave statt Exit (Exit hier, weil's in TMonitor so heißt)
Implizit ... joar, ich war schreibfaul ... statt du überall vor Ort zu machen, kann man auch in der Ableitung die Methoden ala Add usw. überdecken/überschreiben und dort das Enter/Exit/Leave rein tun. Überschreiben (virtual+override) ist besser, falls man zwar die TRingbuffer_Safe<> verwendet, aber die Variable auf TRingbuffer<> stehen bleibt. Der Vorteil am "Externen" ist, dass man es für ALLE Klassen verwenden kann, ohne Diese erst anpassen zu müssen. TMonitor hat den Vorteil, dass es multiplatform ist (CriticalSection ist ja Windows) und dass es angeblich schneller sein soll. Aber der wirkliche Vorteil ist, dass man keine Variable dafür braucht. (OK, die braucht es immernoch, aber sie ist bereits in allen TObject-Nachfahren integriert) |
AW: Ringpuffer Bibliothek veröffentlicht
Hallo,
ich hab' ja noch keine Antworten auf meine Idee mit den leeren überschreibbaren Methoden bekommen. Falls das aber ein geeigneter Ansatz wäre eine intrinsische Variante (die ich auch bevorzugen möchte) umzusetzen darfst du das gerne einbringen! Mache einen entsprechenden Pull Request oder schicke mir die Unit anderweitig zu. Wichtig ist halt, dass alle existierenden Unit Tests bestanden werden. Die Frage für mich wäre auch, wie man Multithreaded Code Unit testen kann... => Würde mich über deinen Beitrag dazu sehr freuen! Grüße TurboMagic |
AW: Ringpuffer Bibliothek veröffentlicht
siehe mein Edit?
Alles Testen ist schwer. Explizit einige bestimmte Sperrszenarien kann man als Test aufbauen, aber prüfen, ob eine Funktion per se threadsave ist, kann nicht getestet werden, außer man führt es milliardenmal mit unterschiedlichen Timings/Auslastungen aus und hofft man trifft zufällig eine problematische Überschneidung. |
AW: Ringpuffer Bibliothek veröffentlicht
Sorry, habe ich noch nicht wirklich gesehen.
Bin gedanklich gerade bei der Übernahme von Code für die DEC (siehe anderen Post von mir von eben). |
AW: Ringpuffer Bibliothek veröffentlicht
Zitat:
zu lassen (ist der Compiler schlau genug das bei Nutzung der Basisklasse als "nop" zu erkennen und somit auszulassen?) oder alle public Methoden als Virtual zu deklarieren und in der abgeleiteten Klasse zu überschreiben? Wie sieht es mit dem XMLDOC aus? Muss man den in der abgeleiteten Klasse duplizieren damit er funktioniert? Grüße TurboMagic |
AW: Ringpuffer Bibliothek veröffentlicht
Zitat:
Wäre aber natürlich gut, wenn wir hier vorher möglichst einen klaren Architekturfavoritän küren könnten ;-) Grüße TurboMagic |
AW: Ringpuffer Bibliothek veröffentlicht
Zitat:
![]()
Delphi-Quellcode:
Bis bald...
var
FInOutStream: TSynQueue; begin FInOutStream := TSynQueue.Create(TypeInfo(TRawByteStringDynArray)); ... Thomas |
AW: Ringpuffer Bibliothek veröffentlicht
Vielleicht, nur zieht man sich damit nicht jede Menge andere Dinge aus mormot mit rein?
Die Ringpuffer Umsetzung die angesprochen war hat den Charme, dass es eine einzelne Unit ist. |
AW: Ringpuffer Bibliothek veröffentlicht
Jetzt alle relevanten Methoden in Enter/Leave zu klammern halte ich für wenig hilfreich, denn das sind in non-threadsafe Fall immer zwei überflüssige Calls. Davon abgesehen wird das in einigen Fällen auch nicht reichen, z.B. wenn man erwartet, dass ein Peek gefolgt von einem Pop ein konsistentes Ergebnis liefert. Aber auch das property Notify ist mit dem direkten Feldzugriff nicht wirklich threadsicher.
Delphi-Quellcode:
in einer thread-safe Version ableiten läuft konträr zur aktuellen Ableitungsphilosophie mit
TRingBuffer
Delphi-Quellcode:
. Man müsste dann womöglich jede Ableitung in zwei Flavors machen:
TObjectRingbuffer
TRingbuffer<T> -> TThreadsafeRingBuffer<T>Das erscheint mir nicht sonderlich sinnvoll. Ein möglicher Ansatz, der den ursprünglichen Ringbuffer unangetastet lässt, wäre ein Wrapper für den Zugriff - analog zu
Delphi-Quellcode:
:
TThreadList
Delphi-Quellcode:
type
TThreadRingBufferWrapper<T> = class private FLock: TObject; FRingBuffer: TRingBuffer<T>; public constructor Create(ARingBuffer: TRingBuffer<T>); destructor Destroy; override; function LockBuffer: TRingBuffer<T>; procedure UnlockBuffer; inline; end; ... constructor TThreadRingBufferWrapper<T>.Create(ARingBuffer: TRingBuffer<T>); begin inherited Create; FRingBuffer := ARingBuffer; FLock := TObject.Create(); end; destructor TThreadRingBufferWrapper<T>.Destroy; begin LockBuffer; try FRingBuffer.Free; inherited Destroy; finally UnlockBuffer; FLock.Free; end; end; function TThreadRingBufferWrapper<T>.LockBuffer: TRingBuffer<T>; begin TMonitor.Enter(FLock); Result := FRingBuffer; end; procedure TThreadRingBufferWrapper<T>.UnlockBuffer; begin TMonitor.Exit(FLock); end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:13 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