AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Rückgabewerte von TCriticalSection?

Ein Thema von BKempf · begonnen am 9. Nov 2004 · letzter Beitrag vom 16. Nov 2004
Antwort Antwort
BKempf

Registriert seit: 1. Jun 2004
103 Beiträge
 
Delphi 6 Enterprise
 
#1

Rückgabewerte von TCriticalSection?

  Alt 9. Nov 2004, 01:14
Ein Thread besitzt einen TTimer und dessen OnTimer-Methode soll alle 50ms einen kleinen Teil einer größeren Aufgabe (Aufräumen von Datenbanken) durchführen (um diese eigentlich sehr plattenintensive Aktion über einen langen Zeitraum zu strecken). Kann ich dafür TCriticalSection verwenden?

Mein Problem ist, daß alle Ereignisse im Kontext desselben Threads stehen, d.h. wenn ich
Delphi-Quellcode:
cs.Enter;
TuWas;
cs.Leave;
schreibe und TuWas so lange dauert, daß der nächste ausgelöste Event wieder
cs.Enter; ausführen will, dann beißt sich der Thread selbst in den Schwanz und bleibt hängen, weil die letzte Instanz der Methode darauf wartet, daß die vorherige cs wieder unlockt (was sie aber nicht tun kann, da momentan die zweite Instanz ausgeführt wird).

Daher bräuchte ich sowas wie
Status:=cs.Enter; das die CriticalSection nicht nur nötigenfalls lockt, sondern mir auch gleich mitteilt, ob sie vorher schon gelockt war oder nicht (und das vor allem nicht durch Multitasking unterbrechbar ist). Entsprechend würde ich nur im zweiten Fall TuWas ausführen und im ersten einfach nichts tun.

Kann TCriticalSection das? Ich kenne nur "Enter" und "Leave" und habe sonst auch nichts in der OH gefunden. Gibt es evtl. andere Typen, die die genannte Funktion haben?
The problem with troubleshooting is that sometimes the trouble shoots back.
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#2

Re: Rückgabewerte von TCriticalSection?

  Alt 9. Nov 2004, 04:01
Critical Sections machen nur in Threads einen Sinn. Wie man sie dort verwendet, kannst du dir in meinem Threading Tutorial. http://tutorials.luckie-online.de angucken.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
BKempf

Registriert seit: 1. Jun 2004
103 Beiträge
 
Delphi 6 Enterprise
 
#3

Re: Rückgabewerte von TCriticalSection?

  Alt 9. Nov 2004, 20:19
Zitat von Luckie:
Critical Sections machen nur in Threads einen Sinn.
Die Critical Section würde innerhalb eines Timerevents verwendet, der seinerseits einem Thread gehört. So gesehen ist das schon eine CS innerhalb eines Threads. Nur habe ich in Erinnerung, daß CSs nur zwischen verschiedenen Instanzen einer Threadklasse bzw. zwischen Instanzen verschiedener Threadklassen funktionieren, und deshalb in meinem Fall nicht verwendet werden können (da es sich immer um ein und dieselbe Instanz desselben Timers und desselben Threads handelt).

Dein Tutorial sehe ich mir aber mal an, danke.
The problem with troubleshooting is that sometimes the trouble shoots back.
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#4

Re: Rückgabewerte von TCriticalSection?

  Alt 9. Nov 2004, 20:23
hast du schon versucht den Timer nach CriticalSection.Enter abzuschalten und wenn du mit "tuwas" fertig bist diesen wieder anzuschalten?
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
BKempf

Registriert seit: 1. Jun 2004
103 Beiträge
 
Delphi 6 Enterprise
 
#5

Re: Rückgabewerte von TCriticalSection?

  Alt 9. Nov 2004, 21:06
Zitat von SirThornberry:
hast du schon versucht den Timer nach CriticalSection.Enter abzuschalten und wenn du mit "tuwas" fertig bist diesen wieder anzuschalten?
(Livemitschnitt meiner Überlegungen, ich bin an das Problem rangegangen mit der festen Überzeugung, daß da irgendwo Deadlocks entstehen würden.)

Nein, einen Timer dauernd ein- und auszuschalten finde ich böse
Wenn ich den Timer abschalte, wäre die CS überflüssig (da keine weiteren Events mehr auftreten können. Schalte ich ihn nicht ab, blockiert sie den Thread. Die CS ist also entweder nicht verwendbar oder überflüssig).
Theoretisch kann bei der Version mit abgeschaltetem Timer dann aber folgendes passieren:

- OnTimer wird aufgerufen, aber es wird gerade noch die Methode gestartet und plötzlich entscheidet sich Windows dafür, einem anderen Programm seine Aufmerksamkeit zu schenken.
- Wenn Windows irgendwann zu dem Programm zurückkehrt, wird OnTimer ein weiteres Mal aufgerufen, weil die 50ms wieder um sind. Der erste OnTimer ist noch nicht abgearbeitet, aber im Stack des Threads liegt der zweite Aufruf (da er jünger ist) weiter oben und wird abgearbeitet. Erste Anweisung ist Timer.enabled:=false.
TuWas wird ausgeführt, danach Timer.enabled:=true. Also alles in Butter?...
Nein, denn da lauert noch der erste, ältere Aufruf, der den Timer wieder abschaltet, TuWas ausführt und den Timer wieder einschaltet, ...

Huch, ich dachte, da würde sich was verklemmen. Ich war davon ausgegangen, daß der Timer sich ausschaltet und dann aus bleibt...

Gut, ein kleines Problem gibt es noch, nämlich wenn Windows so unpassend hin- und herschaltet, daß das Programm schneller OnTimer-Events bekommt, als es sie durch das Multitasking gebremst abarbeiten kann. Aber da muß ich wohl darauf vertrauen, daß sich selbst Win98 kein so gezielt userfeindliches Verhalten einfallen läßt.

Hm, mit dem "Timer dauernd ein- und ausschalten" sollte ich mich vielleicht doch baldmöglichst anfreunden, das scheint die einzige passende Lösung zu sein...

Hach, tut es gut, manchmal laut zu denken

Danke für die Anregungen.
The problem with troubleshooting is that sometimes the trouble shoots back.
  Mit Zitat antworten Zitat
Benutzerbild von jim_raynor
jim_raynor

Registriert seit: 17. Okt 2004
Ort: Berlin
1.251 Beiträge
 
Delphi 5 Standard
 
#6

Re: Rückgabewerte von TCriticalSection?

  Alt 10. Nov 2004, 07:16
Was verwendest du denn für einen Timer? Den normalen TTimer? Dann sollte dir bewusst sein, dass dieser nicht mit Threads arbeitet, sondern nur über Windows-Messages. Windows-Messages werden hintereinander verarbeitet. Du wirst also nie in die Situation kommen, das der Event zwei mal gleichzeitig aufgerufen wird. Problematisch ist nur, wenn deine Event länger als 50ms dauert. Das würde dann bedeuten, das dein Programm nur noch mit dem Timer beschäftigt ist. Allerdings wird es nie passieren, dass das Event zwei mal gleichzeitig läuft.

Hier würde ich dir empfehlen mit Threads zu arbeiten. In dem Execute des Threads kannst du sowas dann machen.

Delphi-Quellcode:
// Abbruch des Threads, wenn die Anwendung geschlossen wurde
while not Application.Terminated do
begin
  TuWas;
  Sleep(50);
end;
Auch hier würde es nie dazu kommen, dass mehrmals gleichzeitig das TuWas aufgerufen wird. Für das Sleep kannst du natürlich auch andere Sachen nutzen um eine Verzögerung hinzubekommen. Ich denke, mit dieser Variante ersparst du dir eine Menge Ärger, ohne zu wissen von was ich da eigentlich Rede

P.S: Ich sehe gerade, dass du ja bereits einen Thread hast. Leider weiss ich garnicht wie ein TTimer im Thread reagiert. Aber auf jeden Fall sollte dann meine Variante die bessere sein
Christian Reich
Schaut euch mein X-COM Remake X-Force: Fight For Destiny ( http://www.xforce-online.de ) an.
  Mit Zitat antworten Zitat
BKempf

Registriert seit: 1. Jun 2004
103 Beiträge
 
Delphi 6 Enterprise
 
#7

Re: Rückgabewerte von TCriticalSection?

  Alt 16. Nov 2004, 16:50
Mein Ansatz ist, daß ich kleine Zeitscheiben definiere, innerhalb derer (und evtl. auch etwas darüber hinaus) die Aufräumaktionen stattfinden sollen. Diese Zeitscheiben sollen im Mittel annähernd eingehalten werden, d.h. wenn die Abarbeitung der Methode mal mehr als die 50 ms benötigt, fällt sie beim nächsten Takt einfach mal aus.
Das eigentliche Problem ist also nicht der Timer an sich, sondern die Notwendigkeit, Daten aus einem Takt (nämlich z.B. den Anteil der verbrauchten Prozessorzeit oder notfalls ein Flag "Nichts verändern, die Methode läuft noch vom vorherigen Takt": boolean) sicher in den folgenden Takt hinüberzuretten - was offenbar nicht mit CriticalSections zu gehen scheint, aber auch nicht ohne das gleichzeitige Lesen und Schreiben einer Variablen (etwa der genannten booleschen) zu riskieren.
Die Idee mit dem Ansatz "Kurz was ausführen, dann sleep(50)" war mir auch schon gekommen, aber ich will für die 50ms nicht das ganze Programm anhalten
Der genannte Thread ist nur einer von insgesamt dreien, von denen einer recht zeitkritisch ist und auch in den Ruhepausen des Aufräumthreads laufen muß.
The problem with troubleshooting is that sometimes the trouble shoots back.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:50 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz