34

私はこれを検索する方法を正確に知りません..だから私は何かを見つけることができませんでした.. :S

Cで時間遅延を実装する必要があります。

たとえば、私は何かをしたいのですが、それから 1 分待ってから、何かを続けます。

それは理にかなっていますか?誰でも私を助けることができますか?

4

18 に答える 18

45

標準 C (C99) ではtime()、次のようにこれを行うために使用できます。

#include <time.h>
:
void waitFor (unsigned int secs) {
    unsigned int retTime = time(0) + secs;   // Get finishing time.
    while (time(0) < retTime);               // Loop until it arrives.
}

ちなみに、これはtime()1 秒の分解能値を返すことを前提としています。それは標準で義務付けられているとは思わないので、調整する必要があるかもしれません。


明確にするために、これがISO C99でこれを行うために私が知っている唯一の方法です(そして、質問には「C」以外のタグが付けられていません。これは、通常、ポータブルソリューションが望ましいことを意味しますが、もちろんベンダー固有のソリューションまだ与えられるかもしれません)。

より効率的な方法を提供するプラットフォームを使用している場合は、必ずそれを使用してください。いくつかのコメントが示しているように、CPU 使用率とバッテリー寿命に関して、このようなタイト ループには特定の問題がある可能性があります。

適切なタイム スライス OS であれば、タイム スライスを継続的に使用するタスクの動的優先度を下げることができますが、バッテリー電力はより問題になる可能性があります。

ただし、Cはホスト環境の OS の詳細については何も指定していません。この回答は ISO C および ISO C のみに対するものです (したがって、Win32 API 呼び出しなどは使用しませんsleep) select

また、POSIXsleepはシグナルによって中断される可能性があることに注意してください。その道を進む場合は、次のようなことを行う必要があります。

int finishing = 0; // set finishing in signal handler 
                   // if you want to really stop.

void sleepWrapper (unsigned int secs) {
    unsigned int left = secs;
    while ((left > 0) && (!finishing)) // Don't continue if signal has
        left = sleep (left);           //   indicated exit needed.
}
于 2010-10-14T05:57:56.467 に答える
17

ほとんどのデスクトップ システムでこれを行う方法は次のとおりです。

#ifdef _WIN32
    #include <windows.h>
#else
    #include <unistd.h>
#endif

void wait( int seconds )
{   // Pretty crossplatform, both ALL POSIX compliant systems AND Windows
    #ifdef _WIN32
        Sleep( 1000 * seconds );
    #else
        sleep( seconds );
    #endif
}

int
main( int argc, char **argv)
{
    int running = 3;
    while( running )
    {   // do something
        --running;
        wait( 3 );
    }
    return 0; // OK
}

タイマーなしのマイクロコンピューター/プロセッサーでそれを行う方法は次のとおりです。

int wait_loop0 = 10000;
int wait_loop1 = 6000;

// for microprocessor without timer, if it has a timer refer to vendor documentation and use it instead.
void
wait( int seconds )
{   // this function needs to be finetuned for the specific microprocessor
    int i, j, k;
    for(i = 0; i < seconds; i++)
    {
        for(j = 0; j < wait_loop0; j++)
        {
            for(k = 0; k < wait_loop1; k++)
            {   // waste function, volatile makes sure it is not being optimized out by compiler
                int volatile t = 120 * j * i + k;
                t = t + 5;
            }
        }
    }
}

int
main( int argc, char **argv)
{
    int running = 3;
    while( running )
    {   // do something
        --running;
        wait( 3 );
    }
    return 0; // OK
}

ウェイトループ変数は微調整する必要があり、それらは私のコンピューターではかなり近くで機能しましたが、周波数スケールの問題により、最新のデスクトップ システムでは非常に不正確になります。したがって、あなたが金属にさらされていて、そのようなことをしていない限り、そこで使用しないでください.

于 2010-10-14T06:42:36.603 に答える
10

sleep(3) の man ページまたはMSDN の Sleep を確認してください

于 2010-10-14T05:39:29.210 に答える
6

多くの実装ではtime、現在の時刻を秒単位で返す関数がありますが、すべての実装がそうするという保証はありません(たとえば、秒ではなくミリ秒返すものもあります)。そのため、より移植性の高いソリューションは、difftime関数を使用することです。

difftimeは、2 つの値の間の秒単位の時間差を返すことがC 標準によって保証されています。そのため、 C 標準のすべての準拠実装で実行される移植可能な時間遅延関数を作成できます。time_t

#include <time.h>

void delay(double dly){
    /* save start time */
    const time_t start = time(NULL);

    time_t current;
    do{
        /* get current time */
        time(&current);

        /* break loop when the requested number of seconds have elapsed */
    }while(difftime(current, start) < dly);
}

timeanddifftime関数に関する1 つの注意点は、 C 標準では粒度が指定されていないことです。ほとんどの実装の粒度は1 秒です。遅延が数秒続く場合はこれで問題ありませんが、遅延関数が1 秒未満の遅延の場合、待機時間が長すぎる場合があります。

移植可能な標準 C の代替手段があります:clock関数です。

このclock関数は、プログラムの呼び出しのみに関連する実装定義の時代の開始以降、プログラムによって使用されたプロセッサ時間に対する実装の最良の概算を返します。時間を秒単位で決定するには、clock関数によって返される値をマクロの値で割る必要がありますCLOCKS_PER_SEC

関数の解決策は、関数のclock解決策と非常によく似ていますtime

#include <time.h>

void delay(double dly){
    /* save start clock tick */
    const clock_t start = clock();

    clock_t current;
    do{
        /* get current clock tick */
        current = clock();

        /* break loop when the requested number of seconds have elapsed */
    }while((double)(current-start)/CLOCKS_PER_SEC < dly);
}

この場合、 と の場合と同様の注意点がありtimeます。関数difftimeの粒度は実装に任されています。clockたとえば、マイクロ秒clock_t単位の分解能を持つ 32 ビット値を持つマシンは、2147 秒 (約 36 分) 後に によって返される値をラップすることになる場合があります。clock

そのため、少なくとも 1 秒続く遅延には遅延関数の実装を使用し、 1 秒未満の遅延には実装を使用することtimeを検討してください。difftimeclock

最後の注意事項:カレンダー時間ではなくプロセッサ時間clockを返します。実際の経過時間と一致しない場合があります (たとえば、プロセスがスリープしている場合)。clock

于 2013-07-29T17:51:22.017 に答える
3

1 分程度の遅延の場合sleep()は、良い選択です。

いつか、1 秒未満の遅延で一時停止したい場合はpoll()、タイムアウトを検討することをお勧めします。

どちらもPOSIXです。

于 2010-10-14T08:02:08.630 に答える
1

試すsleep(int number_of_seconds)

于 2010-10-14T05:40:11.733 に答える
1

sleep(int)良いディレイとして機能します。1 分間:

//Doing some stuff...
sleep(60); //Freeze for A minute
//Continue doing stuff...
于 2010-10-14T05:41:24.557 に答える
0

delay()関数を呼び出すだけです。したがって、プロセスを3秒遅らせたい場合は、delay(3000)を呼び出します...

于 2010-10-14T07:08:05.813 に答える
0

確実に待機して中断されないようにしたい場合は、POSIX で sleep を使用するか、Windows で Sleep を使用してください。POSIX では、スリープには秒単位の時間がかかるため、時間を短くしたい場合は、usleep()マイクロ秒を使用するような種類があります。Windows でのスリープには数ミリ秒かかりますが、それより細かい粒度が必要になることはほとんどありません。

一定時間待機したいが、緊急の場合などに割り込みを許可したい場合があります。スリープはシグナルによって中断される可能性がありますが、この場合はより良い方法があります。

したがって、実際には、イベントまたはタイムアウト付きの条件変数を待つことが実際にわかりました。

Windows では、あなたの呼び出しはWaitForSingleObject. POSIX ではpthread_cond_timedwait.

Windows では、 を使用することもできます。WaitForSingleObjectExその後、 を呼び出して、キューに入れられたタスクで実際にスレッドを「中断」できますQueueUserAPC。WaitForSingleObject(Ex) は、終了した理由を特定するコードを返すため、「TIMEDOUT」ステータスを返すと、実際にタイムアウトしたことがわかります。終了させたいときに待機するイベントを設定します。

条件変数をブロードキャストすることpthread_cond_timedwaitができます。(複数のスレッドが同じスレッドで待機している場合は、それらをすべて起動するためにブロードキャストする必要があります)。ループするたびに、条件をチェックする必要があります。スレッドは現在の時刻を取得して経過したかどうかを確認したり、何をすべきかを判断するために何らかの条件が満たされているかどうかを確認したりできます。ある種のキューがある場合は、それを確認できます。(スレッドは、条件変数を待機していたミューテックスを自動的にロックします。そのため、条件をチェックするときは、その条件にのみアクセスできます)。

于 2011-02-18T12:40:27.113 に答える
0

使用しているオペレーティング システムは何ですか?
Windowsでは、次のようなことができることを知っています:

//include crap
#include <windows.h>

int main () {
  //do things
  Sleep(/* ur wait time in ms */);// wait for param1 ms
  //continue to do things
}
于 2020-08-04T15:17:08.447 に答える
0

ですかtimer

WIN32 の場合はhttp://msdn.microsoft.com/en-us/library/ms687012%28VS.85%29.aspxを試してください

于 2010-10-14T05:39:38.100 に答える
0

C11には、これに特化した機能があります。

#include <threads.h>
#include <time.h>
#include <stdio.h>

void sleep(time_t seconds) {
    struct timespec time;
    time.tv_sec = seconds;
    time.tv_nsec = 0;
    while (thrd_sleep(&time, &time)) {}
}

int main() {
    puts("Sleeping for 5 seconds...");
    sleep(5);
    puts("Done!");
    return 0;
}

これは glibc 2.28 以降でのみ利用可能であることに注意してください。

于 2020-01-29T16:53:38.413 に答える
0

Linux OS での短い遅延 (数マイクロ秒など) には、「usleep」を使用できます。

// C Program to perform short delays
#include <unistd.h>
#include <stdio.h>

int main(){
    printf("Hello!\n");
    usleep(1000000); // For a 1-second delay
    printf("Bye!\n);
    return 0;
于 2021-02-11T19:48:45.887 に答える
-1
system("timeout /t 60"); // waits 60s. this is only for windows vista,7,8
system("ping -n 60 127.0.0.1 >nul"); // waits 60s. for all windows
于 2013-10-31T11:01:17.023 に答える