Ich baue eine Multithread-Anwendung mit pthreads
und brauche einen Thread, um regelmäßig einige Sachen zu überprüfen. In der Zeit dazwischen sollte dieser Thread keine CPU verbrauchen. Geht das mit usleep()
? Ist usleep()
Nicht damit beschäftigt zu warten? Oder gibt es eine bessere Lösung?
Ist usleep() in C als Busy Wait implementiert?
Seebonk
Cnicutar
Die Funktion usleep
wurde aus SUSv4 entfernt. Sie sollten wahrscheinlich verwenden nanosleep
stattdessen oder Timer (setitimer
etc).
Wie R.. in den Kommentaren anmerkt, sollte der Schlaf als geschäftiges Warten implementiert werden:
- Der Thread würde weiterhin die CPU verwenden
- Andere (niedrigere) Threads würden keine Chance bekommen, ausgeführt zu werden
Daher:
- Einige verwenden möglicherweise Signale (ich denke, SUSv3 hat SIGALARM erwähnt?)
- Einige könnten ausgefallene Timer verwenden
-
usleep
ist nicht Teil der C-Bibliothek, AFAIK.– Jens Gustedt
16. November 2011 um 19:13 Uhr
-
@JensGustedt Es ist nicht Standard. Aber
libc
(glibc, bsd libc usw.) hat es normalerweise. Also, falls es jemand hat, es ist die C-Bibliothek.– Cnicutar
16. November 2011 um 19:18 Uhr
-
es ist Standard aber POSIX 🙂
– Jens Gustedt
16. November 2011 um 19:25 Uhr
-
@JensGustedt
kernel.org
erwähnt, dass es nicht in SUSv4 enthalten ist. Und die Suche in SUSv4 danach ergibt nichts.– Cnicutar
16. November 2011 um 19:35 Uhr
-
Es kann nicht als Busy Wait implementiert werden, da dies die Ausführung anderer Threads/Prozesse mit niedrigerer Priorität ausschließen würde.
– R.. GitHub HÖR AUF, EIS ZU HELFEN
17. November 2011 um 5:49 Uhr
Jens Gustedt
(usleep
ist nicht Teil des C-Standards, sondern eines alten POSIX-Standards. Aber siehe unten.)
Nein, die POSIX-Spezifikation von usleep
klar sagt
Die Funktion usleep() bewirkt, dass der aufrufende Thread von der Ausführung suspendiert wird …
Dies erfordert also eindeutig, dass die Ausführung ausgesetzt und die Ressourcen anderen Prozessen oder Threads überlassen werden.
Wie bereits von anderen erwähnt, die POSIX-Funktion nanosleep
wird jetzt ersetzt usleep
und das solltest du nutzen. C (seit C11) hat eine Funktion thrd_sleep
das ist nachempfunden nanosleep
.
Beachten Sie nur, dass sowohl usleep() als auch nanosleep() durch ein Signal unterbrochen werden können. Mit nanosleep() können Sie einen zusätzlichen Zeitspezifikationszeiger übergeben, in dem die verbleibende Zeit gespeichert wird, falls dies geschieht. Wenn Sie also Ihre Verzögerungszeiten wirklich garantieren müssen, sollten Sie wahrscheinlich einen einfachen Wrapper um nanosleep() schreiben.
Beachten Sie, dass dies nicht getestet wurde, aber etwas in dieser Richtung:
int myNanoSleep(time_t sec, long nanosec)
{
/* Setup timespec */
struct timespec req;
req.tv_sec = sec;
req.tv_nsec = nanosec;
/* Loop until we've slept long enough */
do
{
/* Store remainder back on top of the original required time */
if( 0 != nanosleep( &req, &req ) )
{
/* If any error other than a signal interrupt occurs, return an error */
if(errno != EINTR)
return -1;
}
else
{
/* nanosleep succeeded, so exit the loop */
break;
}
} while( req.tv_sec > 0 || req.tv_nsec > 0 )
return 0; /* Return success */
}
Und wenn Sie den Thread jemals für etwas anderes als ein periodisches Timeout aufwecken müssen, werfen Sie einen Blick auf die Bedingungsvariablen und pthread_cond_timedwait()
.
-
Das hat immer amüsiert, da in POSIX-Sleep-Funktionen die angeforderte Zeit nicht nur keine Obergrenze ist (da das System wie bei anderen Betriebssystemen Ihren Thread beliebig später verschieben kann), sondern nicht einmal eine Untergrenze aufgrund von Signalen gebunden. Im Wesentlichen können schlafähnliche Funktionen zurückkehren, wann immer sie es am liebsten haben. 😀
– Matteo Italien
16. Januar 2019 um 16:36 Uhr
Bill Lynch
Unter Linux wird es mit implementiert Nanosleep-Systemaufruf was kein geschäftiges Warten ist.
Verwenden spurIch kann sehen, dass ein Anruf an usleep(1)
übersetzt wird nanosleep({0, 1000}, NULL)
.
usleep()
ist eine Funktion der C-Laufzeitbibliothek, die auf Systemtimern aufbaut.
nanosleep()
ist ein Systemaufruf.
Nur MS-DOS und dergleichen implementieren die Sleep-Funktionen als Busy Waits. Jedes aktuelle Betriebssystem, das Multitasking bietet, kann ohne weiteres eine Schlaffunktion als einfache Erweiterung von Mechanismen zum Koordinieren von Aufgaben und Prozessen bereitstellen.
Ich denke, pthreads hat a
yield()
Funktion, die nützlich sein könnte.– Kerrek SB
16. November 2011 um 18:19 Uhr
usleep
hat nichts mit C als Sprache zu tun, es ist eine Funktion des Betriebssystems.– Jens Gustedt
16. November 2011 um 19:11 Uhr
@KerrekSB:
pthread_yield
wird die CPU-Auslastung nicht verringern, es wird nur dazu führen, dass der Thread im Verhältnis zu anderen Threads der gleichen Prioritätsstufe vorübergehend depriorisiert wird.– Dietrich Ep
16. November 2011 um 19:44 Uhr