![]() |
AW: verhindern: Klick auf Titelleiste stoppt Programm
@SirThornberry
falls Deine Antwort an mich gerichtet war, es ging mir darum daß IMHO eine CriticalSection eineindeutig zu sein hat wenn sie den gewünschten Effekt haben soll, oder bin ich hier auf dem ganz falschen Dampfer. |
AW: verhindern: Klick auf Titelleiste stoppt Programm
Nein, du bist auf dem richtigen Dampfer. SirThornberry fährt mit dem Code auf der Titanic und der Eisberg ist nicht mehr weit. ;)
|
AW: verhindern: Klick auf Titelleiste stoppt Programm
Zitat:
Und ich verstehe auch nicht warum es einmalig sein muss? Ich kann so viele TCriticalSection-Instanzen wie ich möchte/benötige. Manchmal kann es Sinn machen mehrere Instanzen zu benutzen. Es geht ja nur darum (in einer MultiThread-Umgebung) einerseits die Zugriffe auf den Speicher zu regeln (gleichzeitiges Lesen und Schreiben erzeugt halt Zugriffsfehler) und andererseits (vergleichbar mit den Transaktionen im DB-Umfeld) konsistente Daten zu erhalten (bei geschickter Verwendung). Kleines Beispiel zu den konsistenten Daten:
Delphi-Quellcode:
function TMyThread.GetPoint : TPoint;
begin FCS.Enter; try Result := FPoint; finally FCS.Leave; end; end; procedure TMyThread.Execute; begin while not Terminated do begin // Diese Daten sind immer konsistent bei der Abfrage FCS.Enter; try FPoint.X := 1; FPoint.Y := 1; finally FCS.Leave; end; // Hier ist die Konsistenz nicht gewährleistet - also schlechter Code :o) FCS.Enter; try FPoint.X := 2; finally FCS.Leave; end; // Erfolgt jetzt ein Zugriff von aussen, dann hat FPoint ja den Wert (2,1) FCS.Enter; try FPoint.Y := 2; finally FCS.Leave; end; end; end; |
AW: verhindern: Klick auf Titelleiste stoppt Programm
Wenn mehrere Threads aufeinander warten müssen, dann dürfen sie auch nur die gleiche CriticalSection nutzen. Das ist wie bei einer Ampelkreuzung, die darf auch nur von einer Schaltung gesteuert werden. Hätte jede Ampel ihre eigene Steuerung würde es krachen.
|
AW: verhindern: Klick auf Titelleiste stoppt Programm
Eine CriticalSection soll ja nur vor dem gleichzeitigen Lesen und Schreiben schützen.
Somit kommt es darauf an, was man schützen möchte, denn nur ein Thread kann die CriticalSection betreten. Alle anderen warten solange, bis die CriticalSection wieder betreten werden kann und dann geht wieder ein Thread in diese CriticalSection. Somit kann man mit einer CriticalSection auch einen/mehrere Threads blockieren. Schlimmstenfalls sind sogar Deadlocks möglich. Aus diesem Grund kann es von Vorteil sein, unterschiedliche CriticalSections zu benutzen um eine ungewollte Blockade zu vermeiden. Ansonsten verspielt man den Vorteil von Queue und hat sich wieder ein Synchronize draus gebaut. |
AW: verhindern: Klick auf Titelleiste stoppt Programm
BWT, wir gehen Offtopic, vielleicht sollten wir einen neue Thread "CriticalSection" aufmachen
Aber die Criticalsection wird ja nur von denen beachtet die sie nutzen. Wenn Du einen Bereich als Critical kennzeichnest in den ein anderer schreiben kann dann muß er auch so zugreifen, wenn kein anderer zugreifen kann brauchst Du keine CriticalSection. Ich habe mal ein Beispiel für das angehängt wo ich das Problem sehe. Button 1 Klicken und direkt danach Button2 klicken in TMyThread.Execute die Auskommentierung wechslen, das gleiche passiert auch wenn man statt einer anderen, gar keine CriticalSection verwendet.
Delphi-Quellcode:
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs,SyncObjs, StdCtrls; type TMyThread = CLass(TThread) protected procedure Execute; override; public constructor Create( CreateSuspended : Boolean ); destructor Destroy; override; End; TForm1 = class(TForm) Button1: TButton; Button2: TButton; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; FCS ,FCS2: TCriticalSection; txt:String; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); var tc:Cardinal; begin FCS.Enter; txt := 'Button1'; tc := GetTickCount; while GetTickCount < (tc + 5000) do Application.ProcessMessages; Showmessage(txt); FCS.Leave; end; procedure TForm1.Button2Click(Sender: TObject); begin TMyThread.Create(false); end; procedure TForm1.FormCreate(Sender: TObject); begin FCS := TCriticalSection.Create; FCS2 := TCriticalSection.Create; end; procedure TForm1.FormDestroy(Sender: TObject); begin FCS.Free; FCS2.Free; end; { TMyThread } constructor TMyThread.Create(CreateSuspended: Boolean); begin inherited; FreeOnTerminate := true; end; destructor TMyThread.Destroy; begin inherited; end; procedure TMyThread.Execute; begin inherited; // das liefert Thread als Ergebnis in //Showmessage von Button1Click FCS2.Enter; txt := 'Thread'; FCS2.Leave; // das liefert das erwartete Ergebnis in //Showmessage von Button1Click { FCS.Enter; txt := 'Thread'; FCS.Leave; } end; end. |
AW: verhindern: Klick auf Titelleiste stoppt Programm
Aus diesem Grund hänge ich die Instanz von TCriticalSection auch direkt an den Thread, um dessen Properties so zu schützen, dass kein gleichzeitiger Zugriff darauf erfolgen kann. Mittels Getter und Setter wird dann automatisch die CS betreten/verlassen. Somit wird der Zugriff auf selbige extrem stressfrei.
Wir sollten tatsächlich einen neuen Thread draus machen ... |
AW: verhindern: Klick auf Titelleiste stoppt Programm
Ich habe gerade mal in meinem Delphi 2006 nachgeschaut. Das gibt es die Methode schon
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:32 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