Mailinglist Archive: opensuse-de (4938 mails)

< Previous Next >
Re: Jobkontrolle
  • From: eilert@xxxxxxxxxxxxxxxxxxxxxxxx (Eilert Brinkmann)
  • Date: Mon May 29 11:18:59 2000
  • Message-id: <xtt1z2lsixo.fsf@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>



Bernd Brodesser <B.Brodesser@xxxxxxxxxxxxxx> wrote:
* Eilert Brinkmann schrieb am 29.Mai.2000:

Das ist offensichtlich richtig, obwohl in man 3 sleep von nanosleep
nicht die Rede ist, dort wird nur alarm(2) erwähnt. Dient wohl nur zur
verwirrung, denn alarm wird definitiv nicht aufgerufen.

In `man 3 sleep' steht nur, daß sleep() unter Verwendung von SIGALARM
implementiert sein *könnte* (unter Solaris ist es das laut
Dokumentation auch), und das man es deshalb nicht mit Aufrufen von
alarm() vermischen sollte:

sleep() may be implemented using SIGALRM; mixing calls to
alarm() and sleep() is a bad idea.

Das scheint vor allem ein Tip für portable Programmierung zu sein,
heißt aber noch nicht, daß die Implementierung in einer bestimmten
Bibliothek unbedingt so aussehen muß.

Nun bekommt der Prozeß ein anderes Signal und wird fortgesetzt. Da der
nanosleep-Aufruf durch ein Signal unterbrochen wurde, kehrt er sofort
mit einer Fehlermeldung (errno == EINTR) zurück, bevor die Zeit
abgelaufen ist.

Wenn ich es richtig verstanden habe, so hat aber nanosleep gerade
dafür den zweiten Eintrag. Damit sollte es doch zu bewerkstelligen
sein, daß nanosleep neu gestartet wird.

Ja, allerdings scheint die Implementierung von sleep() das nicht zu
tun. Es ist auch fraglich, ob das wirklich sinnvoll wäre. Schließlich
würde das bedeuten, die gesamte Zeitverzögerung durch den
sleep()-Aufruf um die Zeit zu verlängern, die der Prozeß gestoppt war,
und das könnte fast genauso unerwünscht sein wie die Verkürzung. Im
Falle einer vorzeitigen Unterbrechung liefert sleep() immerhin die
Anzahl der noch nicht geschlafenen Sekunden zurück, damit ließe sich
vielleicht was anfangen.

Würde es sleep bzw. nanosleep genauso machen, käme ihre Zeit
durcheinander. Denn die Zeit, wo der Prozeß angehalten ist, würde
nicht mitgezählt. Dafür hat nanosleep den zweiten Eintrag. Aber
irgendwie klappt das mit sleep nicht. Oder habe ich es doch nicht
richtig verstanden.

Im allgemeinen ist sleep() ganz bequem, aber wenn es wirklich drauf
ankommt, sollte man wohl besser per Hand mit nanosleep() arbeiten, auf
die Rückgabewerte achten und vielleicht auch noch mit gettimeofday()
die Systemzeit im Auge behalten und Zeitdifferenzen überprüfen, falls
es auf die geschlafene Realzeit ankommt.

-> tail -5 bla
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0

rt_sigprocmask ist offensichtlich ein Systemaufruf, aber
man rt_sigprocmask sagt nur:

Kein Manual-Eintrag für rt_sigprocmask vorhanden

Die rt_sig...()-Funktionen sind für den Umgang mit Realtime-Signalen
vorgesehen, ansonsten dürften sie ihrer Bedeutung nach in etwa den
"herkömmlichen" Funktionen entsprechen. Trotzdem ärgerlich, daß es
keine Doku dazu gibt :-( Ich vermute mal, daß diese Funktionen hier
intern von der sleep(3)-Implementierung verwendet werden. Das Ändern
der Behandlung von SIGCHLD ist wahrscheinlich eine allgemeine
Vorkehrung und unabhängig davon, ob der konkrete Prozeß irgendwelche
Kinder hat.

rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
nanosleep({1000, 0}, 0xbffff07c) = -1 EINTR (Interrupted system
call)
^^^^^^^^^^
Was will uns das sagen? Offensichtlich eine Adresse, aber worauf?

Auf ein struct timespec mit der noch nicht geschlafenen Zeit. Fragt
sich, warum strace hier nicht wie sonst den Inhalt der Struktur
ausgibt.

Ich habe mal strace -f -o bla sleep 1000 gemacht mit anschließendem im
Hintergrundschicken:

[...]
4736 nanosleep({1000, 0}, <unfinished ...>
4736 --- SIGCONT (Fortgesetzt) ---
4736 <... nanosleep resumed> 0xbffff5ec) = -1 ENOSYS (Function not
implemented)

Hier also ist der SIGCONT zu finden. Aber warum nur hier, und ein Kind
habe ich auch nicht gefunden, überall nur die gleiche Prozeßnummer,
das ganze strace lang.

Gut zu wissen, daß man bei Verwendung von -o auch das Signal zu sehen
bekommt (ging mit einfacher Umleitung nicht). Zum fehlenden Kind siehe
oben.

Das SIGCONT kommt also im nanosleep, was auch nicht weiter überrascht.
nanosleep gibt ein ENOSYS zurück, womit sleep nichts anfangen kann und
daher abbricht. Das heißt, sleep bekommt es gar nicht mehr zu Gesicht,
oder? Sonst würde da doch ein _exit stehen. Aber ohne -f gibt strace
auch ein _exit aus. Was denn jetzt?

Anscheinend verhält sich strace mit der Option -f etwas seltsam. Ohne
bekommt man auch korrekt ein EINTR zu sehen, und dieses ENOSYS dürfte
eigentlich nicht sein.

Irgendwie bin ich jetzt noch verwirrter.

Bis auf die seltsamen Variationen in der strace-Ausgabe sollte jetzt
das meiste geklärt sein, oder?

Einfach die Zeit, die der Prozeß angehalten war zu übergehen, wäre
sicher auch nicht richtig, aber so ist es sicher falsch.

ACK (siehe oben).

Eilert

--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Eilert Brinkmann -- Universitaet Bremen -- FB 3, Informatik
eilert@xxxxxxxxxxxxxxxxxxxxxxxx - eilert@xxxxxxx - eilert@xxxxxxxxxxxxxx
http://www.informatik.uni-bremen.de/~eilert/

---------------------------------------------------------------------
To unsubscribe, e-mail: suse-linux-unsubscribe@xxxxxxxx
For additional commands, e-mail: suse-linux-help@xxxxxxxx


< Previous Next >