Anzeige:
Ergebnis 1 bis 9 von 9

Thema: Zuverlässigkeit Timeout select()

  1. #1
    Registrierter Benutzer
    Registriert seit
    02.07.2004
    Beiträge
    456

    Zuverlässigkeit Timeout select()

    Hello again... *träller*

    äh... kann mir einer sagen, wie zuverlässig die Timeout Angabe im Aufruf von select() ist? Wenn ich dem select() ein Timeout von 5ms gebe und keiner der überwachten Deskriptoren meldet sich zurück, sprich das Timeout schlägt zu, wie genau schlägt dieses Timeout zu? Kann ich 100% davon ausgehen, daß ein 5ms Timeout auch wirklich 5ms dauert? Oder kann das aufgrund verschiedener Umstände auch mal länger dauern (bis zu 100ms eventuell)?

    Wir haben in unserer Software Timer implementiert, die auf select() basieren. Ein Test-Timer, eingestellt auf 5ms, kam dabei aber sporadisch erst nach >100ms zum Zuge. Kann es eventuell an mangelnder Zuverlässigkeit von select() liegen, daß der Timer so ungenau ist?

    Wenn ja, welche Möglichkeiten gibt es noch, um Timer, die Callback Funktionen nach Ablauf aufrufen, auf ähnliche, doch zuverlässigere Weise zu implementieren, als mit select() Timeouts?

    Danke

    Gruß,
    Hendrik

    edit: ich hab das jetzt mal mit poll() statt select() ausgetimed, also die Zeit gemessen, die poll bei einem bestimmten übergebenen Intervall tatsächlich bis zum Ablauf des Timeouts braucht:

    Code:
    poll() took more time than given in 'interval'! 83002 > 64000 (93 overflows)
    poll() took more time than given in 'interval'! 90232 > 67000 (94 overflows)
    poll() took more time than given in 'interval'! 86676 > 2000 (95 overflows)
    poll() took more time than given in 'interval'! 90129 > 41000 (96 overflows)
    poll() took more time than given in 'interval'! 97396 > 73000 (97 overflows)
    poll() took more time than given in 'interval'! 95541 > 92000 (98 overflows)
    poll() took more time than given in 'interval'! 95486 > 73000 (99 overflows)
    poll() took more time than given in 'interval'! 91116 > 55000 (100 overflows)
    poll() took more time than given in 'interval'! 97569 > 28000 (101 overflows)
    poll() took more time than given in 'interval'! 97498 > 75000 (102 overflows)
    poll() took more time than given in 'interval'! 6837 > 6000 (103 overflows)
    poll() took more time than given in 'interval'! 91402 > 84000 (104 overflows)
    poll() took more time than given in 'interval'! 97148 > 74000 (105 overflows)
    poll() took more time than given in 'interval'! 93794 > 21000 (106 overflows)
    poll() took more time than given in 'interval'! 95748 > 72000 (107 overflows)
    poll() took more time than given in 'interval'! 95358 > 69000 (108 overflows)
    Die erste Zahl nach der Meldung ist die Anzahl Mikrosekunden, die Poll laut zwei gettimeofday Aufrufen (einer vor, einer nach poll() ) tatsächlich gebraucht hat. Die zweite Zahl ist das angegebene Interval in Millisekunden * 1000. Die Zahl in Klammern ist ein Zähler, der die Anzahl übergelaufene Timeouts zählt. Wie kann es angehen, daß das Timeout von poll() länger dauert, als in "interval" angegeben?

    Hier der Code von der Poll-Funktion in unserer Software:
    Code:
    	int inline Poll(int interval)
    	{
    		int g_interval = interval;
    		static int overflow_counter = 0;
    
    		struct timeval tv1, tv2;
    		int retval = 0;
    
    		gettimeofday(&tv1,NULL); // Zeitmessung poll() begin
    			retval = ::poll(poll_handles, fd_max+1, interval);
    		gettimeofday(&tv2,NULL); // Zeitmessung poll() ende
    
    		unsigned long long time1 = 0, time2 = 0, diff = 0;
    
    		time1 = (tv1.tv_sec * 1000000) + tv1.tv_usec;
    		time2 = (tv2.tv_sec * 1000000) + tv2.tv_usec;
    		diff = time2 - time1;
    
    		if( g_interval > 0 && diff > (unsigned long long)(g_interval * 1000) )
    		{
    			printf("poll() took more time than given in 'interval'! %lli > %lli (%i overflows)\n", diff, (unsigned long long)(g_interval * 1000), overflow_counter++ );
    		}
    
    		return retval;
    	}
    Ich denke, bei select() verhielte es sich ähnlich, oder?!
    Geändert von 7.e.Q (07-10-2005 um 09:32 Uhr) Grund: Weitere Informationen

  2. #2
    Registrierter Benutzer
    Registriert seit
    25.10.2004
    Beiträge
    819
    Zitat Zitat von 7.e.Q
    Kann ich 100% davon ausgehen, daß ein 5ms Timeout auch wirklich 5ms dauert? Oder kann das aufgrund verschiedener Umstände auch mal länger dauern (bis zu 100ms eventuell)?
    Linux ist kein Echtzeit-Betriebssystem, deshalb kann es schonmal länger dauern.
    Es gibt aber einen Patch, der behauptet, Linux Echtzeitfähig zu machen, google mal nach RTLINUX

  3. #3
    Registrierter Benutzer
    Registriert seit
    05.09.2002
    Ort
    Neuhausen
    Beiträge
    320
    Der Aufruf von select() mit einem Timeout garantiert nur, dass der Aufrufer mindestens so lange wie angegeben schlafen gelegt wird. Da der Kernel nicht echtzeitfähig [1] ist kann keine maximal-Zykluszeit garantiert werden.

    Dazu kommt noch, dass der im Kernel verwendete preemptive Scheduler üblicherweise mit einer Zykluszeit von 10ms arbeitet. D.h. kürzere Unterbrechnungen sind nicht möglich [2].

    Das gilt übrigens auch für usleep(). (Wird auch oft über select() implementiert).

    Gruss, Andy

    [1] Harte Echtzeitfähigkeit. Da der Scheduler auch realtime-Threads zur verfügung stellt können in einem gewissen Masse auch Echtzeitfähigkeit ermöglicht werden, aber nicht im einstelligen Millisekunden-Bereich oder darunter.
    [2] Nicht ganz korrekt, Prozesse können auch unterbrochen werden, wenn sie einen System-Call absetzen. Bei neueren 2.6er Kernel kann übrigens die Zykluszeit aus drei Vorgaben gewählt werden, ohne das händische Eingriffe im Code notwendig sind.

  4. #4
    Registrierter Benutzer
    Registriert seit
    02.07.2004
    Beiträge
    456
    RTAI scheint eine interessante Sache zu sein, diesbezüglich. Jedoch finde ich leider nirgends den Patch für die von uns verwendete Kernel Version 2.6.7. Wenn jemand einen Link dazu hat, immer her damit!

  5. #5
    Registrierter Benutzer
    Registriert seit
    02.07.2004
    Beiträge
    456
    So, habe mal den Kernel auf RTAI 3.1 gepatched und läuft.

    Was muss ich nun in meiner Software an Stelle von select() tun, damit ich die gleiche Funktionalität habe, wie mit select() selbst, nur eben, daß das Timeout von select() mit Sicherheit genau kommt? Die selben Fragen gelten übrigens auch für poll(), da wir an der Stelle am Umstellen sind.

    Eine weitere Frage ist, ob und wie ich Software für ein RTAI gepatchtes Linux mit dem Cygwin übersetzen kann?

  6. #6
    Registrierter Benutzer
    Registriert seit
    22.03.2001
    Beiträge
    650
    Da musst Du in die Dokue zu RTAI sehen.
    Entscheiden ist nur RT-Funktionen zu benutzen, da nur die harte Echtzeit haben,
    weil der Linux-Kernel nur als Thread niedriger Priorität läuft.

  7. #7
    Registrierter Benutzer
    Registriert seit
    22.03.2001
    Beiträge
    650
    Nachtrag: Unter Cygwin wird RTAI sicherlich nicht richtig funktionieren können, da es nicht direkt sonder als Thread unter MS-Win läuft.

  8. #8
    Registrierter Benutzer
    Registriert seit
    02.07.2004
    Beiträge
    456
    Es ging nicht darum, RTAI/LXRT unter Cygwin zum Laufen zu bekommen, sondern mit Cygwin Software zu übersetzen, die nachher auf einem Linux-System mit RTAI/LXRT Unterstützung läuft und RTAI/LXRT nutzt. Wir benutzen den Cygwin, um mit unseren Windows Workstations Software für unsere Linux Systeme zu übersetzen. Bisher funktioniert das auch, jedoch noch nicht für Software mit RTAI Unterstützung.

  9. #9
    Registrierter Benutzer
    Registriert seit
    22.03.2001
    Beiträge
    650
    Unter MS-Win ist das schwierig, da einige Dateinamen unter DOS/Win nicht zulässig sind; beispielsweise case-sensitive Dateinamen (z. B. beispiel.foo und Beispiel.foo) und Dateinamen mit wildcards. Daran sollte schon das Auspacken der Kernel-Quellen scheitern.

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •