![]() |
Zugriff synchronisieren
Hallo,
ich plage mich mit folgenden Problem. In einen Ringpuffer werden Daten zyklisch geschrieben und gelesen. Das funktioniert auch wie gewünscht. Den Lese- und den Schreibvorgang habe ich in einer kritischen Sektion eingeschlossen. Also
Delphi-Quellcode:
Um das Teil zu stressen schreibe ich über einen Timer zyklisch Daten und Lese diese wieder.
FLock : TCriticalSection;
FLock.Acquire; FLock.Enter; schreibe Daten in den Buffer FLock.Release; Schreibe ich jetzt zusätzlich Daten über einen Schalter in den Buffer, kommt eine Speicherschutzverletzung. Das heist, dass der als kritische Sektion gekapselte Vorgang offensichtlich nicht abgeschlossen ist, und der über Schalter ausgelöste asynchrone Schreibzugriff in den gerade laufenden fuscht. Hat wer eine Idee, wie ich den Schreibvorgang in den Buffer absichern kann, ohne das eine Unterbrechung möglich ist? Mit Gruß Peter |
Re: Zugriff synchronisieren
Kann es sein das jede Klasse ihre eigene TCritical hat? Wo deklariertst Du diese?
Ferner würde ich auch
Delphi-Quellcode:
und
Flock.Enter
Delphi-Quellcode:
nutzen ;-)
Flock.Leave
|
Re: Zugriff synchronisieren
Zitat:
In dieser ist Flock : TCriticalSection declariert. Vor Aufruf von PutBlock (einen Datenblock in den Ringpuffer schreiben) wird als erstes ein FLock.Enter ausgeführt. Vor dem Verlassen der Funktion ein FLock.Release. Warum ist Enter und Leave besser ? Danke. Mit Gruß Peter Edit: Rechtschreibfehler |
Re: Zugriff synchronisieren
Hi,
// WEGEN ROTEM KASTEN GESTRICHEN/GELÖSCHT ... Ansonsten kannst du ja auch schauen, ob die Sektion betreten wird. Schreib dir einfach ein einfachen Test, der in der criticalSection eine Endlosschleife enthält oder einfach die Section nicht freigibt. Dann lässt du noch per ShowMessage einen Hinweis aufpopen, wenn jmd. diese Sektion betritt. Wenn hier ein solcher Hinweis kommt, wenn du die Sektion über einen Schalter betreten möchtest, wärend die Section eigentlich gesperrt ist, dann hast du etwas geschafft was eigentlich nicht möglich sein sollte. Gruß Der Unwissende |
Re: Zugriff synchronisieren
Hallo,
das Aquire / Enter muss nicht zweimal aufgerufen werden (siehe Hilfe)
Delphi-Quellcode:
Was mich hier stutzig macht, ist das "Andere Threads blockieren".
LockXY.Acquire; { Andere Threads blockieren }
try Y := sin(X); finally LockXY.Release; end; Wenn du über einen Timer schreibst, bist du ja im gleichen Thread! Falls ich das richtig verstehe, nützt also eine critical section nichts, ich würde es mal mit nem Mutex probieren. Heiko |
Re: Zugriff synchronisieren
Wie oft wird die Klasse TRingBuffer erzeugt?? Mehr als 1x?
Warum Du
Delphi-Quellcode:
nutzen sollst. Hm.... gute Frage!? Ich arbeite mit Leave. Habe keine Probleme beim Synconisieren. Klammerst Du auch mit Synchronize aus?
Flock.Leave
Die Delphi-Hilfe verrät folgendes:
Delphi-Quellcode:
Dein Code:
Mit Acquire wird die Anbindung aller anderen Threads an diesen kritischen Abschnitt so lange blockiert, bis eine der Methoden Release oder Leave aufgerufen wird. Acquire hat denselben Effekt wie die Methode Enter.
Delphi-Quellcode:
Meiner Meinung nach betrittst Du die Sections quasi 2x. Kann aber auch sein das ich falsch liege. :roll:
FLock.Acquire;
FLock.Enter; .... @hoika: Da war wohl einer schneller :mrgreen: |
Re: Zugriff synchronisieren
Zitat:
Aber der Hinweis oben sollte richtig sein. die klasse gibt es nur einmal und da ich diese im gleichen Kontext (Thread) verwende, kann die Criticalsection ja nicht funktionieren. Ich rufe die Schreibroutine einmal von einem Timer auf und dann zusätzlich über einen Schalter. Mutex habe ich noch nicht verwendet, werde es aber sofort mal probieren. Gruß Peter |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:31 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 by Thomas Breitkreuz