Ist usleep() in C als Busy Wait implementiert?

Lesezeit: 3 Minuten

Benutzer-Avatar
Seebonk

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?

  • 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

Benutzer-Avatar
Cnicutar

Die Funktion usleep wurde aus SUSv4 entfernt. Sie sollten wahrscheinlich verwenden nanosleep stattdessen oder Timer (setitimeretc).

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

Benutzer-Avatar
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

Benutzer-Avatar
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.

1179060cookie-checkIst usleep() in C als Busy Wait implementiert?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy