- 1. gettimeofday, settimeofday 日付と時刻の取得 / 設定
- 2. nanosleep n(ナノ)秒単位でスリープ
- 3. timeradd, timersub, timercmp 日時計算
1. gettimeofday, settimeofday 日付と時刻の取得 / 設定
#include <sys/time.h>
int gettimeofday(struct timeval *tp, struct timezone *tzp);
int settimeofday(const struct timeval *tp, const struct timezone *tzp);
当然、gettimeofday で取得、settimeofday で設定になります。
struct timeval 型は 以下の形式
struct timeval
{
long tv_sec; // 1970 年 1月 1日からの秒数
long tv_usec; // およびμ(マイクロ)秒数
};
struct timezone 型は、タイムゾーンを表すもので、本来、夏時間を定義して日時を扱うためのものでしたが、コンピュータで扱うには不向き(政治的問題が大きくからむ)であることから廃止の方向ですので、明示的に NULL を引数にします。
そもそも、どっかの馬鹿の政治家くらいしか、夏時間なんてことは考えないのですよ。
2. nanosleep n(ナノ)秒単位でスリープ
#include <time.h>
int nanosleep(const struct timespec *rqtp, struct timespec *rmtp);
基本は rqtp で指定した時間スリープします。
きっちり待ち時間分スリープした場合は、戻り値は 0 になります。
スリープ中にシグナルによって起動された場合、rmtp が NULL でなければ rmtp に残りの時間が設定されます。
このとき戻り値には -1 が設定され、error に EINTR が設定されます。
struct timespec 型は 以下の形式
struct timespec
{
time_t tv_sec; // 秒
long tv_nsec; // n(ナノ)秒
};
いささか汎用性に欠けるので、例えば、精度をミリ秒単位までとし、シグナルが発生しないものとすれば例えば
int myNanosleep(int second, int millisecond)
{
struct timespec rqtp = {};
struct timespec rmtp = {};
rqtp.tv_sec = second;
rqtp.tv_nsec = millisecond * 1000 * 1000;
return nanosleep(&rqtp, &rmtp);
}
のような関数を書けば、秒単位・ミリ秒単位で実行を停止させることができます。
3. timeradd, timersub, timercmp 日時計算
これは内容は関数でなくマクロらしいです。
#include <sys/time.h>
void timeradd(struct timeval *a, struct timeval *b, struct timeval *res);
void timersub(struct timeval *a, struct timeval *b, struct timeval *res);
int timercmp(struct timeval *a, struct timeval *b, CMP);
timeradd は a と b を足した結果を res に返します。
timersub は a から b を引いた結果を res に返します。
timercmp は a と b を CMP に示す記号が真(0以外)か偽(0)かを返します。
CMP には「<」「>」「!=」のいずれかを使います。
これは、文字列やキャラクタではないので、ダブルコーテーションやシングルコーテーションで囲まないようご注意ください。
「>=」や「==」もコンパイルエラーにはなりませんが、コンパイラによって結果が異なることがあるらしい。
下記のソースを書いて
#include <limits.h>
#include <stdio.h>
#include <sys/time.h>
static void timerset(struct timeval* c, time_t* time_c);
int main(int argc, char* argv[])
{
for (int i=0; i<5; i++)
{
struct timeval c = {};
time_t time_c = 0;
timerset(&c, &time_c);
printf("前回との時刻差は[%02ld]秒です\n", time_c);
printf("前回との時刻差は[%02ld.%06ld]秒です\n", c.tv_sec, c.tv_usec);
printf("\n");
}
return 0;
}
void timerset(struct timeval* c, time_t* time_c)
{
static unsigned char virgin = 1;
static struct timeval a = {};
struct timeval b = {};
static time_t time_a = 0;
time_t time_b = 0;
if (virgin != 0)
{
gettimeofday(&a, NULL);
time_a = time(NULL);
virgin = 0;
return;
}
gettimeofday(&b, NULL);
time_b = time(NULL);
*time_c = time_b - time_a;
time_a = time_b;
timersub(&b, &a, c);
a = b;
}
実行すると下記の結果が得られます。
前回との時刻差は[00]秒です
前回との時刻差は[00.000000]秒です
前回との時刻差は[00]秒です
前回との時刻差は[00.000038]秒です
前回との時刻差は[00]秒です
前回との時刻差は[00.000001]秒です
前回との時刻差は[00]秒です
前回との時刻差は[00.000001]秒です
前回との時刻差は[00]秒です
前回との時刻差は[00.000001]秒です
当たり前のことですが time では得られない差を gettimeofday で得ることができるわけです。
|