まず最初に。それを行うことに頼るのではなく、現在の時刻も出力するためにいくつかの追加のコードlaunchd
を入れてください。
標準出力のフラッシュ動作が異なる可能性があります。
標準出力が対話型デバイス (コマンド ラインからの実行など) であると判断できる場合、それは行バッファーされます。遅延の前に「前」の行がフラッシュされます。
そうしないと、完全にバッファリングされるため、プログラムが終了するまで (または、(たとえば) 4K のバッファ サイズに達するまで) フラッシュが発生しない可能性がありlaunchd
ます。
行にタイムスタンプを付ける C コードを取得すると、次のような問題があるかどうかがわかります。
#include <stdio.h>
#include <time.h>
#include <unistd.h>
int main (void) {
printf("%d: Before delay\n", time(0));
unsigned int delay = 3000000;
while( (delay=usleep(delay)) > 0);
printf("%d: After delay\n", time(0));
return 0;
}
バッファリングが問題になる理由を確認するには、上記のプログラムを次のように実行することを検討してください。
pax> ./testprog | while read; do echo $(date): $REPLY; done
Tue Jan 31 12:59:24 WAST 2012: 1327985961: Before delay
Tue Jan 31 12:59:24 WAST 2012: 1327985964: After delay
バッファリングにより、プログラムの終了while
時に両方の行がループに表示されるため、プログラム内で 3 秒離れて生成されたにもかかわらず、同じタイムスタンプが取得されることがわかります。12:59:24
実際、次のように変更すると、次のようになります。
pax> ./testprog | while read; do echo $(date) $REPLY; sleep 10 ; done
Tue Jan 31 13:03:17 WAST 2012 1327986194: Before delay
Tue Jan 31 13:03:27 WAST 2012 1327986197: After delay
while
「周囲の」プログラム(ループ、またはあなたの場合は)が見た時間はlaunchd
、プログラム自体から完全に切り離されていることがわかります)。
第二に、失敗するusleep
可能性のある関数です! また、-1 を返すことで失敗する可能性がありますが、これはほとんどゼロより大きくありません。
つまり、失敗した場合、遅延は実質的にゼロになります。
単一 UNIX 仕様には、次のように記載されていますusleep
。
正常に完了すると、usleep() は 0 を返します。それ以外の場合は、-1 を返し、エラーを示すために errno を設定します。
usleep() 関数は、次の場合に失敗する可能性があります: [EINVAL]: 1,000,000 マイクロ秒以上で指定された時間間隔。
それは確かにあなたのコードに当てはまりますが、起動前ではなく起動後に機能する理由を説明するのは難しいでしょう.
興味深いことに、Mac OSX のドキュメントには EINVAL が記載されていませんが、スリープが外部から中断された場合は EINTR が許可されます。繰り返しますが、確認すべきことがあります。
次のような方法でこれらの可能性を確認できます。
#include <stdio.h>
#include <time.h>
#include <errno.h>
#include <unistd.h>
int main (void) {
printf("%d: Before delay\n", time(0));
unsigned int delay = 3000000;
while( (delay=usleep(delay)) > 0);
printf("%d: After delay\n", time(0));
printf("Delay became %d, errno is %d\n", delay, errno);
}
私が気付いたもう1つのことは、コードから、スリープしusleep
ていない(残りの)マイクロ秒数を返し、すべてが完了するまでループすると想定しているようですが、その動作はマニュアルページによって裏付けられていません。
nanosleep
これは (渡された構造体を更新して、残り時間を返すのではなく含むようにすることで) 行うことを知っていますが、 usleep
0 または -1 しか返しません。
このsleep
関数はそのように動作し、残りの秒数を返します。可能であれば、代わりにその関数を使用することを検討するかもしれません。
いずれにせよ、実際の問題が何であるかを確認できるように、上記の (最後の) コード セグメントを引き続き実行します。