AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Threads, welche Lösung haltet Ihr für eleganter ?
Thema durchsuchen
Ansicht
Themen-Optionen

Threads, welche Lösung haltet Ihr für eleganter ?

Ein Thema von DataCool · begonnen am 27. Jun 2006 · letzter Beitrag vom 29. Jun 2006
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von DataCool
DataCool

Registriert seit: 10. Feb 2003
Ort: Lingen
909 Beiträge
 
Delphi 10.3 Rio
 
#1

Threads, welche Lösung haltet Ihr für eleganter ?

  Alt 27. Jun 2006, 23:35
Hi,

ich habe einen Thread, der alle 250 Millisekunden etwas machen sollen.
Jetzt bieten sich mir 2 Möglichkeiten das ganze zu realisieren :

Möglichkeit 1:
Delphi-Quellcode:
  While not terminated do begin
    // do some work
    // sleep(250);
  end;
Möglichkeit 2:
Delphi-Quellcode:
Var bExit : Boolean;
    wRes : Word;
begin
  bExit := false;
  repeat
    wRes := WaitForSingleObject(hCloseEvent,250);
    if wRes = WAIT_OBJECT_0 + 0 then
      bExit := true
    else
      doSomeWork;
  until (bExit) or (terminated);
end;
Welche Möglichkeit würdet Ihr bevorzugen und warum ?

Danke und Gruß

Data
Der Horizont vieler Menschen ist ein Kreis mit Radius Null, und das nennen sie ihren Standpunkt.
  Mit Zitat antworten Zitat
Benutzerbild von Lemmy1
Lemmy1

Registriert seit: 28. Nov 2004
Ort: Ismaning
184 Beiträge
 
Delphi 2006 Professional
 
#2

Re: Threads, welche Lösung haltet Ihr für eleganter ?

  Alt 28. Jun 2006, 00:10
Hi

Ich würde von den beiden 1 auswählen, weil einfacher. Allerdings stimmt das "alle 250 ms" nicht, wenn der eigentliche Vorgang länger als 0 Millisekunden dauert.

Sinnvoller wäre es doch:
- Uhrzeit abfragen
- Task ausführen
- Uhrzeit abfragen
- Uhrzeitdifferenz in ms ausrechnen
- Differenz von 250ms abziehen
- Wenn mehr als 0ms Different ==> Sleep(diff)


So kommt man dem "alle 250 ms" wesentlich näher...
Daniel
www.nemu.com - The N64 Emulator
  Mit Zitat antworten Zitat
Basilikum

Registriert seit: 9. Aug 2003
389 Beiträge
 
Delphi 7 Professional
 
#3

Re: Threads, welche Lösung haltet Ihr für eleganter ?

  Alt 28. Jun 2006, 07:12
Zitat von Lemmy1:
Sinnvoller wäre es doch:
- Uhrzeit abfragen
- Task ausführen
- Uhrzeit abfragen
- Uhrzeitdifferenz in ms ausrechnen
- Differenz von 250ms abziehen
- Wenn mehr als 0ms Different ==> Sleep(diff)
da wäre es doch einfacher, direkt mit MSDN-Library durchsuchenCreateWaitableTimer und Co. zu arbeiten...
  Mit Zitat antworten Zitat
Benutzerbild von DataCool
DataCool

Registriert seit: 10. Feb 2003
Ort: Lingen
909 Beiträge
 
Delphi 10.3 Rio
 
#4

Re: Threads, welche Lösung haltet Ihr für eleganter ?

  Alt 28. Jun 2006, 11:04
Hi,

vielleicht sollte ich zusätzlich noch sagen das der Thread nichts macht ausser ein ReadLn auf eine IdTcpClient Connection auszuführen. Wenn das ReadLn korrekte Daten erhält wird ein neuer Thread erzeugt der die Daten verarbeitet.

Gruß Data
Der Horizont vieler Menschen ist ein Kreis mit Radius Null, und das nennen sie ihren Standpunkt.
  Mit Zitat antworten Zitat
Dax
(Gast)

n/a Beiträge
 
#5

Re: Threads, welche Lösung haltet Ihr für eleganter ?

  Alt 28. Jun 2006, 11:07
Hmm... Dann setz doch den ReadTimeout des Clients auf INFINITE
  Mit Zitat antworten Zitat
Benutzerbild von DataCool
DataCool

Registriert seit: 10. Feb 2003
Ort: Lingen
909 Beiträge
 
Delphi 10.3 Rio
 
#6

Re: Threads, welche Lösung haltet Ihr für eleganter ?

  Alt 28. Jun 2006, 11:14
Hi,

@Dax: die Idee ist zwar nicht schlecht führt aber zu Problemen, wenn der Thread beendet werden soll und dann im ReadLn hängt bis Daten kommen

Gruß Data
Der Horizont vieler Menschen ist ein Kreis mit Radius Null, und das nennen sie ihren Standpunkt.
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#7

Re: Threads, welche Lösung haltet Ihr für eleganter ?

  Alt 28. Jun 2006, 11:21
Willst du in einem Thread warten, also ihn eine Zeitspanne stoppen, dan immer deine 2. Lösung benutzen. Das ist nicht nur eleganter (hat damit nichts zu tun) sondern es ist RICHTIGER !

Dein Event auf das er wartet wird in einer separaten Methode des Threadobjektes zb. .Stop; oder .Finish; etc.pp. ausgelöst und somit terminiert der Thread sofort und nicht erst nach X Millisekunden wie beim primitive Sleep().

Allerdings sollte es sogar so sein das du WaitForMultipleObjects() benutzt. Du benötigst dann Zugriff auf min. 2 Events gleichzeitig.

1.) dein Stop/Termierungs Event, so wie du es oben schon hast, um den Thread schnell und sauber zu terminieren.
2.) ein Data-Event. Also eigentlich ein Event das signalsiert das du nun mit ReadLn von zb. deinem Socket Daten abholen kannst.

In diesem Moment wartest du im WaitForMultipleObjects() immer INFINITE.

Erst DAS wäre eine absolut saubere Anwendung von Threads. Denn Threads habe auf einem Single-CPU Prozessor nur dann einen effektiven Nutzen wenn sie über die Events des OS signalisiert bekommen wann sie was abzuarbeiten haben, und ansonsten die meiste Zeit schlafen, also nichts an Rechenzeit kosten. Sockets, COM, USB usw. Treiber unter Windows unterstützen alle die Asynchrone Kommunikation per Events gesteuert (siehe Overlapping). Nur per Events und Threads kommt man vom Polling (als schechteste Alternative) weg.

Davon abgesehen kann das OS nur über diesen Weg auch eine saubere Synchronisation Threadübergreifend zur Verfügung stellen. Denn die Signalisierung eines Events arbeitet Hand in Hand mit den Synchronisationsobjekten unter Windows und auch dem Messagequeue.

Gruß Hagen
  Mit Zitat antworten Zitat
Angel4585

Registriert seit: 4. Okt 2005
Ort: i.d.N.v. Freiburg im Breisgau
2.199 Beiträge
 
Delphi 2010 Professional
 
#8

Re: Threads, welche Lösung haltet Ihr für eleganter ?

  Alt 28. Jun 2006, 11:28
if würde mir sowas konstruieren:

Delphi-Quellcode:
while not terminated do
  begin
  x:=GetTickCount;
  ..
  ..
  ..
  if (x+250) > GetTickCount then
    Sleep((x+250)-GetTickCount);
  end;
oder so...
Martin Weber
Ich bin ein Rüsselmops
  Mit Zitat antworten Zitat
Benutzerbild von DataCool
DataCool

Registriert seit: 10. Feb 2003
Ort: Lingen
909 Beiträge
 
Delphi 10.3 Rio
 
#9

Re: Threads, welche Lösung haltet Ihr für eleganter ?

  Alt 28. Jun 2006, 11:29
@negaH:

Das hatte ich fast vermutet deshalb habe ich die Frage hier online gestellt.
Mit WaitForMultipleObjects() arbeite ich in einem anderen Thread da gibt es dann 2 Events einmal zu Beenden und einmal das etwas in der ToDo Liste ist was abgearbeitet werden muss.
Da mache ich es genauso wie Du vorgeschlagen hast.

Beim oben genannten Thread kann es allerdings kein 2tes Event signalisieren, weil ich ja gar nicht weiss wann die Gegenseite Daten ins Socket schickt. Deshalb die Idee mit WaitforSingleObject.

Zeitspanne X(in diesem Fall 250 ms) auf das Ende Signal warten ansonsten erstmal schauen, ob Daten im Socket-Buffer sind(wenn ja diese verarbeiten) und danach wieder Zeitspanne X warten usw.

Oder hast Du ne bessere Idee ?

Gruß Data
Der Horizont vieler Menschen ist ein Kreis mit Radius Null, und das nennen sie ihren Standpunkt.
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#10

Re: Threads, welche Lösung haltet Ihr für eleganter ?

  Alt 28. Jun 2006, 12:46
Zitat:
Beim oben genannten Thread kann es allerdings kein 2tes Event signalisieren, weil ich ja gar nicht weiss wann die Gegenseite Daten ins Socket schickt. Deshalb die Idee mit WaitforSingleObject.
Doch das gibt es auch da. Denn deine Socket Komponenten gehen übers WinSock API des OS und das stellt asynchrone Kommunikation (Overlappings und Events) zur Verfügung. Das Problem sind die VCL Komponenten die du benutzt, bzw. genauergesagt die Unfähigkeit der Programmierer die diese VCL gecodet haben. Harte Worte ich weis aber es ist halt eine Tatsache.

Du solltest jetzt mal schauen ob deine Komponenten ein Eventbasiertes ReadLn() oder so unterstützen.

Der "Aufwand" lohnt sich auf alle Fälle. Denn ohne diese Events bleibt dir nur noch dein Weg über ein zeitliches Polling. Bei 250ms Timeout heist dies das im Durchschnitt dein Thread ca. 125ms zeitverzögert die Socket ausliest. 125ms dauert ein Traceroute um die halbe Welt über mehrere Server hinweg. In 125ms überträgt man in einem 100MBit LAN bis zu 1 Megabytes an Daten. Du hast also mit deinen 250ms bzw. dann durchschnittlich gerechnet 125ms ein sehr schlechte Antwortzeit. Wenn du nun darüber nachdenkst das auch zb. 50ms zu verkürzen dann überschreitest du einen Breakeven Point zwischen schnelle Reaktionszeit und zeitlichem Aufwand nachzuschauen ob was im Socket empfangen wurde. Denn die Anfrage ob der Socket Daten enthält wird selber pa Millisekunden dauern können. Sagen wir mal extrem gerechnent 10ms. Dhj. alle 50ms erwacht dein Thread und benötigt dann 10ms um festzustellen das NICHTS im Socket liegt. Ein sehr schlechtes Laufzeitverhalten und dein Thread frisst dann enorm Rechenzeit für NICHTS. Das sind dann die Programme die uns alle so nerven, sie blockieren unsere Rechner, erzeugen enorme Wartezeiten beim Booten etc.pp. und das alles für NICHTS und nur weil die Programmierer die EINFACHE Variante gewählt haben (im Grunde genommen aber Mist gemacht haben).

Wie du siehst in jedem Falle wäre ein Eventbasiertes System vorzuziehen. Mit einem Polling, egal wie, handelt man sich nur Performanceprobleme zu ungunsten des gesamten Systemes ein.


Beispiel: Warum gibt es in den INDY Komponenten eine idAntiFreeze Komponente ?

Wenn INDY intern immer mit Events und Overlapping in seinen Threads arbeiten würde dann kann die Anwendung/der Prozess garnicht mehr einfrieren, wie auch ? Ich möchte jetzt nicht die INDYs schlecht machen, es ist ein großartiges Tool, und ich bin mir auch nicht 100%'tig sicher wie deren Thread Management arbeitet, aber obige Frage ist definitiv eine berechtigte Frage !


Gruß Hagen
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 07:15 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