web-dev-qa-db-ja.com

Cにミリ秒単位の代替スリープ機能はありますか?

Windowsでコンパイルされたソースコードがいくつかあります。 Red Hat Linuxで実行するように変換しています。

ソースコードには<windows.h>ヘッダーファイルが含まれており、プログラマーはSleep()関数を使用してミリ秒の期間待機しています。これはLinuxでは機能しません。

ただし、sleep(seconds)関数を使用できますが、それは秒単位の整数を使用します。ミリ秒を秒に変換したくありません。 Linuxでのgccコンパイルで使用できる代替スリープ機能はありますか?

113
ant2009

はい-古い POSIX 標準が定義されています usleep() なので、これはLinuxで利用可能です:

   int usleep(useconds_t usec);

記述

Usleep()関数は、呼び出しスレッドの実行を(少なくとも)usecマイクロ秒の間中断します。スリープは、システムアクティビティによって、またはコールの処理に費やされる時間によって、またはシステムタイマーの粒度によって、わずかに長くなる場合があります。

usleep()マイクロ秒を要するため、ミリ秒単位でスリープするには入力に1000を掛ける必要があります。


usleep()は非推奨になり、その後POSIXから削除されました。新しいコードの場合、 nanosleep() が推奨されます。

   #include <time.h>

   int nanosleep(const struct timespec *req, struct timespec *rem);

記述

nanosleep()は、少なくとも*reqで指定された時間が経過するか、呼び出しスレッドでハンドラーの呼び出しをトリガーするか、プロセスを終了する信号が配信されるまで、呼び出しスレッドの実行を中断します。

構造timespecは、ナノ秒の精度で時間間隔を指定するために使用されます。次のように定義されます。

       struct timespec {
           time_t tv_sec;        /* seconds */
           long   tv_nsec;       /* nanoseconds */
       };
156
caf

このクロスプラットフォーム機能を使用できます:

#ifdef WIN32
#include <windows.h>
#Elif _POSIX_C_SOURCE >= 199309L
#include <time.h>   // for nanosleep
#else
#include <unistd.h> // for usleep
#endif

void sleep_ms(int milliseconds) // cross-platform sleep function
{
#ifdef WIN32
    Sleep(milliseconds);
#Elif _POSIX_C_SOURCE >= 199309L
    struct timespec ts;
    ts.tv_sec = milliseconds / 1000;
    ts.tv_nsec = (milliseconds % 1000) * 1000000;
    nanosleep(&ts, NULL);
#else
    usleep(milliseconds * 1000);
#endif
}
40
Bernardo Ramos

usleep() の代わりに、POSIX 2008で定義されていません(POSIX 2004まで定義されていましたが、明らかにPOSIX準拠の歴史を持つLinuxおよびその他のプラットフォームで利用可能)、POSIX 2008標準定義 nanosleep()

nanosleep-高解像度スリープ

#include <time.h>
int nanosleep(const struct timespec *rqtp, struct timespec *rmtp);

nanosleep()関数は、rqtp引数で指定された時間間隔が経過するか、呼び出しスレッドにシグナルが配信されるまで、現在のスレッドの実行を中断します。そのアクションは、シグナルキャッチ関数を呼び出すか、プロセス。引数値がスリープ解像度の整数倍に切り上げられるため、またはシステムによる他のアクティビティのスケジューリングのために、中断時間は要求よりも長くなる場合があります。ただし、信号によって中断される場合を除き、一時停止時間は、システムクロックCLOCK_REALTIMEで測定されるrqtpで指定された時間よりも短くてはなりません。

nanosleep()関数を使用しても、信号のアクションやブロックには影響しません。

31

sleep を超えて、NULLファイル記述子セットを使用した謙虚な select を使用すると、マイクロ秒の精度で一時停止でき、SIGALRMの複雑さのリスクがありません。

sigtimedwaitおよびsigwaitinfo は同様の動作を提供します。

24
pilcrow
#include <unistd.h>

int usleep(useconds_t useconds); //pass in microseconds
13
Anonymous