8

私の目的はwhile、定義された時間 (この例では 90 秒) ループを実行することです。正確に 90 秒である必要はありませんが、1 ~ 2 秒の誤差は許容されます。この目的のために clock()` 関数を使用することにしました:

int main(void){
      clock_t start, end;
      volatile double elapsed;
      start = clock();
      int terminate = 1;
      while(terminate)
      {
              end = clock();
              elapsed = ((double) (end-start)) / (double) CLOCKS_PER_SEC *1000;
              printf("elapsed time:%f\n",elapsed);
              if(elapsed >= 90.0)
                        terminate = 0;
               usleep(50000);
       }
      printf("done..\n");
    return 0;
}

ラップトップ (x86、3.13 カーネル、gcc 4.8.2) で実行すると、ストップウォッチは完了までに72 秒を計測します。elapsed(私のラップトップで秒単位の精度を得るには1000が必要でした)

ARM デバイス (armv5tejl、3.12 カーネル、gcc 4.6.3) で実行すると、コードを完了するのに58 秒かかります。(armv5で使用100する必要がありました)。elapsed

室温でコードを実行するので、クロックは安定しているはずです。カーネルがスレッドをスリープ状態にし、それらを起動する時間などに不正確さがあることはわかっています。したがって、前に述べたように、完璧なタイミングが得られるとは思っていませんが、ある程度の精度はあるはずです。

私はusleep(でもnanosleep)のみを使用しようとしましたが、解像度も良くありませんでした. 最後に、システム時間 (時、分、秒) を取得して経過時間を計算する一番下のコードを考え出します。そして、それは良い精度で動作します。

使用するのにコストがかからない別のソリューションがあるのだろうか?

typedef struct{
    int hour;
    int minute;
    int second;
} timeInfo;

timeInfo getTimeInfo(void){
    timeInfo value2return;
    time_t rawtime;
    struct tm * timeinfo;
    time(&rawtime);
    timeinfo = localtime(&rawtime);
    value2return.hour = timeinfo->tm_hour;
    value2return.minute = timeinfo->tm_min;
    value2return.second = timeinfo->tm_sec;
    return value2return;
}

int checkElapsedTime(const timeInfo *Start, const timeInfo *Stop, const int Reference){
    if(Stop->hour < Start->hour){
        printf("1:%d\n", (Stop->hour +24) *3600 + Stop->minute *60 + Stop->second - (Start->hour *3600 +Start->minute * 60 + Start->second));
         if( ( (Stop->hour +24) *3600 + Stop->minute *60 + Stop->second - (Start->hour *3600 +Start->minute * 60 + Start->second)) >= Reference )
            return 0; //while(0): terminate the loop
         else
             return 1; //while(1)
    }else{
        printf("2:%d\n",Stop->hour *3600 + Stop->minute *60 + Stop->second - (Start->hour *3600 +Start->minute * 60 + Start->second));
        if( (Stop->hour *3600 + Stop->minute *60 + Stop->second - (Start->hour *3600 +Start->minute * 60 + Start->second)) >= Reference )
            return 0;
        else
            return 1;
    }
}

int main(void){

    timeInfo stop, start = getTimeInfo();
    int terminate = 1;
    while(terminate)
    {
        stop = getTimeInfo();
        terminate = checkElapsedTime(&start, &stop, 90);
        usleep(5000); //to decrease the CPU load
    }

    printf("terminated\n");

    return 0;
}

最後に、 内で実行する必要がありpthreadます。

4

3 に答える 3

7
  1. time()対を使用しclock()ます。コーディングの目標は、使用されたプロセッサー時間ではなく、経過した経過時間を判別することです。

    現在のコードは、プロセスの経過時間 * 1000 を計算し、それを 90 秒と比較しました。

    clock()@uesp が暗示した は、「クロック関数は、使用されるプロセッサ時間を決定します」を返します。C11dr §7.27.2.1 2.

    time()「時間関数は現在のカレンダー時間を決定します」を返します§7.27.2.4 2

    difftime()2 の差を見つけtime_t(ユニット/タイプが何であれ)、差を秒単位で返すという素晴らしい仕事をします。

    int main(void) {
       time_t start, end;
       double elapsed;  // seconds
       start = time(NULL);
       int terminate = 1;
       while (terminate) {
         end = time(NULL);
         elapsed = difftime(end, start);
         if (elapsed >= 90.0 /* seconds */)
           terminate = 0;
         else  // No need to sleep when 90.0 seconds elapsed.
           usleep(50000);
       }
       printf("done..\n");
       return 0;
     }
    
  2. マイナー: 注: を使用する場合clock()、 は必要ありません* 1000。gcc を実行している Windows ベースのマシンでclock()は、呼び出しプロセスの CPU 時間も返されました。

    elapsed = ((double) (end-start)) / (double) CLOCKS_PER_SEC *1000;
    elapsed = ((double) (end-start)) / CLOCKS_PER_SEC;
    
  3. マイナー: は必要ありませんvolatileelapsedこのコードが原因で変更されているだけです。

    // volatile double elapsed;
    double elapsed;
    
于 2014-08-24T23:05:02.440 に答える
1

アラームを使用して信号をキャッチします。シグナルハンドラはプロセスの実行を中断します。pthread_cancelを試すこともできます。個々の実行時間tのループまたはスリープ ベースの方法は、時間tまでに不正確になる可能性があります。ループが長時間実行され、タイトな実行パスである場合、スリープまたはブレークは問題をまったく解決しません。

于 2014-08-24T23:25:54.187 に答える
1

最初のバージョンが機能しないように見える理由は、Linux ではclock()リアルタイムではなく、使用された CPU 時間を測定するためです (こちらを参照)。プロセスをスリープ状態にしているため、実際の時間と CPU 時間は一致しません。解決策は、2 番目の例のように実際の時刻を確認することです。

Windowsclock()では実際の時刻が表示されることに注意してください (こちらを参照)。

于 2014-08-24T20:47:44.420 に答える