Autor Beitrag
atarigold
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 84

WIN XP, Linux 2.4
D7, Delphi 2006 Prof
BeitragVerfasst: So 14.03.04 22:32 
Hallo,

ich habe schon einige Beiträge in diesem Forum zum Thema "Delay" gelesen, aber noch keine Lösung für mein Problem entdeckt, aber vielleicht gibt
es ja eine ganz einfache Lösung.

Mein Programm soll regelmäßig (alle 0,5 s) Daten eines Meßgerätes lesen, weiterhin andere Geräte in unregelmäßigen Abständen (z.T. abhängig von den Meßwerten) steuern. Da bei der Steuerung der externen Geräte gewartet werden muß bis die Aktion beendet ist, bevor die nächste Aktion ausgeführt werden kann, brauche ich mehrere Delay-Funktion die möglichst unabhängig voneinander arbeiten.

Die regelm. Messwertabfrage ist über eine ttimer-Komponente realisiert. Die Genauigkeit ist ausreichend.

Ein kurzer Wartezyklus über eine weitere tt-timer-Komonenten nach dem Schema

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
procedure TMessung.wait(zeit: integer);
 //zeit = Wartezeit in 0,1 s - Einheiten
 begin
   timer1.interval:=zeit*100;
   timer1.enabled:=true;
   while timer1.enabled = true do Application.ProcessMessages; 
 end;


funktioniert bei kurzen Wartezeiten noch akzeptabel.

Bei einem weiteren Delay (nach obigem Schema) mit längerer Wartezeit, werden die anderen Prozeduren weitgehend blockiert. Prozessorauslastung steigt auf 100 %. Die API-Funkion GetTickCount habe ich ohne Erfolg auch schon probiert.

Für Hilfe wäre ich sehr dankbar.

Moderiert von user profile iconPeter Lustig: Delphi-Tags hinzugefügt
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: So 14.03.04 23:02 
Entweder du kuckst dich mal nach Suche in: Delphi-Forum, Delphi-Library DELAY um oder baust in deine Schleife ein Application.Processmessages und ein Sleep(1) ein.
atarigold Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 84

WIN XP, Linux 2.4
D7, Delphi 2006 Prof
BeitragVerfasst: Mo 15.03.04 00:04 
Hallo Luckie,

die Antwort hilft mir nicht wirklich weiter. Applikation.ProcessMessages ist bereits eingebaut (sorry Codeauszug ist mir beim Einfügen etwas verrutscht). Sleep legt doch nicht eine einzelne Funktion oder Prozedur lahm sondern das ganze Programm (thread), oder habe ich Diskussionsbeiträge hierzu falsch verstanden ?

Mein Problem ist vielleicht auch schwer verständlich:

Ich benötige mehrere Wartezyklen, die sich überschneiden, da mehrere Geräte (Konkret: Ventile (Reaktionszeit < 2 s) und Spritzenpumpen(Wartezeit 1 bis 20 s) angesteuert werden müssen. Wenn die Aktivitäten streng nacheinander folgen, gibt es natürlich kein Problem, aber es sollen einzelne Aktivitäten parallel stattfinden. Die Geräte werden teilweise einzeln über eine Schnittstelle (RS 232) teilweise aber gemeinsam über einen Treiber (für PCI-AD-Wandler-Karte oder USB-Karten) angesprochen.

Bei Delay-Suche habe ich keine geignete Lösung gefunden, alles was ich ausprobiert habe, führte dazu, dass die zuletzt gestartete lange Warteschleife, die anderen ebenfalls verzögert (bei CPU-Last = 100 % nicht verwunderlich). Aber vielleicht habe ich "die einfache" Lösung einfach übersehen.
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mo 15.03.04 06:42 
Sollte natürlich Sleep(0) heißen:
Bill Gates hat folgendes geschrieben:

A value of zero causes the thread to relinquish the remainder of its time slice to any other thread of equal priority that is ready to run. If there are no other threads of equal priority ready to run, the function returns immediately, and the thread continues execution.


Aber wenn was parallel laufen soll, hast du schon mal über Threads nachgedacht? Btw. was stört dich an der 100% CPU Auslastung? Ich bin froh, wenn meine CPU was für ihr teures Geld macht. Nur sollte es so sein, dass dein Programm auch Rechenzeit abgibt, wenn andere Prozesse sie brauchen.
atarigold Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 84

WIN XP, Linux 2.4
D7, Delphi 2006 Prof
BeitragVerfasst: Di 16.03.04 13:56 
Hallo Luckie,

Ich habe jetzt mit Sleep (0) und Sleep (1) probiert, das Ergebnis war leider nicht das gewünschte.

Wenn mehrere Prozeduren, (wie oben) aufgebaut, benutzt werden, wird nur die jeweils zu letzt gestartete ausgeführt.
Erst nach Beendigung wird in die zuerst gestartete zurückgesprungen, wobei jedoch die Wartezeit korrekt abgearbeitet wird.
Solange also die zuletzt getartete Warteschleife bereits vor der Ende der Laufzeit der vorherigen beendet wird, funktionier's wunderbar,
bei Überschneidungen stimmt die 1. Wartezeit nicht mehr (zu lang um den Betrag der Überschneidung). :(

Application.ProzessMessages erlaubt zwar Benutzereingaben. Es werden auch ggf. Routinen abgearbeitet (z. B. bei Onclick-Ereignis), aber danach geht's wieder zurück in die "letzte" Warteschleife.
Sleep (0) hat keinen für mich erkennbaren Effekt.
Sleep (1) senkt zumindest die Prozessorlast, sicherlich vorteilhaft bei weiteren threads .....
um die ich leider wohl nicht herumkomme.
Leider, weil in der "gewachsenen" Software einiges geändert werden müsste und die Synchronisation nicht einfach werden wird .Ich blättere schon in deinem Tutorial.

________________
Brainiac
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Di 16.03.04 14:30 
Warum gibst du eigentlich nicht jedem der Objekte einen eigenen Timer der in dem Gewünschten Interval für das jeweilige Objekt auslöst.
Sorry... vielleicht habe ich dein Problem auch nicht verstanden...
MaxiTB
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 679

Win2000, WinXp, Workbench ;-)
D7 Ent, VS2003 Arch.
BeitragVerfasst: Di 16.03.04 14:45 
::atari

Du kanst noch so viele Application.ProcessMessages aufrufen - wenn deinen proceduren im selben Threat sind, werden sie nicht ausgeführt.

Grund: Application.ProcessMessages arbeitet nur die Nachrichten von Windows ab. Deine Procedure hängt aber nicht von Messages ab, daher wird sie nicht aufgerufen.

Einzige Lösung für dein Problem: Wenn du paralell Abläufe abarbeiten willst, dann mußt du mit threads arbeiten (da hat Luckie durchaus recht). Den die Lösung mit dem Timer ist für deine zwecke schlicht und ergreifend sinnlos (der ist zu ungenau und Zuverläßlichkeit tendiert gegen Null, besonders bei höherer Auslastung).

_________________
Euer Mäxchen
Wer früher stirbt, ist länger tot.
atarigold Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 84

WIN XP, Linux 2.4
D7, Delphi 2006 Prof
BeitragVerfasst: Mi 17.03.04 14:07 
Hallo Maxi,

danke für die Erklärung. Bevor ich mich an Threads versuche eine kleine Nachfrage:

Das ttimer nicht gerade durch Präzision glänzt war mir bekannt. Aber wenn ichs neu machen muss, dann möchte ich die Genauigkeit natürlich schon etwas mitverbessern - Ziel: 0,05 s)
Erreiche ich mit der API-Funkton GetTickCount diese Genauigkeit ?

atarigold
MaxiTB
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 679

Win2000, WinXp, Workbench ;-)
D7 Ent, VS2003 Arch.
BeitragVerfasst: Mi 17.03.04 14:12 
::atari

Bei dem Timer gehts nicht um Präzesion sondern um Zuverläßlichkeit. Bei großer Auslastung wird nämlich einfach die WM_TIMER vom System verworfen und du kannst im schlechtesten Fall gar keine Nachricht bekommen.

0,05 sec sind mit GetTickCount durchaus drinnen - das Problem ist aber nicht die Genauigkeit der Funktion, sondern das Windows kein real time OS ist; daher ist nicht garantiert, daß dein Prozess zu einem bestimmten Zeitpunkt aktiv ist. Daraus folgt, daß die Ungenauigkeit durch das Multitasking des OS unvorhersehbar sein kann.

Bestes Beispiel: Jemand legt eine CD ein ...

_________________
Euer Mäxchen
Wer früher stirbt, ist länger tot.
atarigold Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 84

WIN XP, Linux 2.4
D7, Delphi 2006 Prof
BeitragVerfasst: Mi 17.03.04 15:55 
Hallo Maxi,

da hast du natürlich völlig recht. Dein Szenario ist absolut zutreffend.
Ich habe aufgrund entsprechender eigener Erfahrungen auf dem Steuerungsrechner nur die nötigste Hard- und Software installiert. Das löst zwar das Problem nicht wirklich, aber leider gibt's bei uns im Job einen Hausstandard und der heißt Microsoft, also OS =Windows.

schönen Gruß
atarigold
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mi 17.03.04 19:47 
atarigold hat folgendes geschrieben:
da hast du natürlich völlig recht. Dein Szenario ist absolut zutreffend.
Ich habe aufgrund entsprechender eigener Erfahrungen auf dem Steuerungsrechner nur die nötigste Hard- und Software installiert. Das löst zwar das Problem nicht wirklich, aber leider gibt's bei uns im Job einen Hausstandard und der heißt Microsoft, also OS =Windows.

Was hat das mit der Lösung deines Problems mittels Threads zu tun? :roll: