一定周期実行プログラムの実装方法

このQ&Aのポイント
  • UNIX環境での、プログラムを一定周期実行させる方法についてご教授ください。
  • 具体的には、50msの周期で無限ループするプログラムを実装したいです。
  • 現在考えている方法は処理時間を計測して、残りの時間をsleepで待たせる方法ですが、他に良い方法はありますか?
回答を見る
  • ベストアンサー

一定周期実行プログラム

UNIX環境での、プログラムを一定周期実行させるプログラミング方法についてご教授下さい。 例えば、50msの周期で、無限ループするプログラムです。 while(1) { t1=clock(); (処理1); t2=clock(); passtime=(t2-t1)/CLOCKS_PER_SEC; time=0.05-passtime; tmp=(int)(1000000*time); usleep(tmp); } まず、思い付いたプログラムは、処理1に掛かった時間を計算し、50msから処理に掛かった時間を引いた時間をsleepで待たせるプログラムです。clock()は精度が低いようですが・・・他に何かいい方法はないでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.1

settimer()とSIGALRMを使ったタイマー割り込みとかどうですか。 http://www.linux.or.jp/JM/html/LDP_man-pages/man2/setitimer.2.html マルチスレッド処理で周期管理と処理本体を分ける、なんて方法も考えられなくはないですが。 あとusleep()は古くてぼちぼち仕様から外されるようなのでnanosleep()を使ったほうがいいですね。

redroof22
質問者

お礼

ありがとうございました。 nanosleep()を使ってみます。

関連するQ&A

  • プログラムのループの周期を設定する方法

    C/C++でプログラムを作成していますが,(MicroSoft Visualstadio C++6.0)で int main() { time[1000]; clock_t t1,t2; t2 = 0; for(int i = 0;i < 1000;i++) { . . Sleep(10) t1 = clock(); time[i] = t1-t2; t2 = clock(); } //エクセルでtime[]を書き出す } としてfor分の中のループ1回分の周期を10msにしようとしているのですが,time[]をエクセルで書き出すと15msになってしまいます. ループ1回分を一定の時間で処理させるにはどうしたらよいのでしょうか. ループ1回分の周期は50ms以下で実行できれば問題ありません.また誤差1ms未満であれば問題ありません(できればあまり大きくないほうがよい).上のプログラムではSleepを使ってますが別にこだわっている訳ではなくほかに方法が分からなかっただけです.できれば簡単なプログラムのようなものを付けて,分かる方はどうか教えてください.

  • プログラムの実行を中断

    標準ライブラリにプログラムを指定した時間だけ停止する、というような関数はあるでしょうか? 自分でも似たような関数を作ったのですが、負荷が大きいらしく動作が指定した時間よりも遅れてしまうことがあります。 #include <ctime> void sleep(int time) { tm *present; time_t clock; int begin; time(&clock); present=localtime(&clock); begin=present->tm_sec while(begin!=present->tm_sec-time){ time(&clock); present=localtime(&clock); } return; }

  • clock()関数の誤差

    プログラムの実行時間の計測について質問させていただきます。 現在,実行時間の計測でclock()関数を使っているのですが誤差が出ます。 timeコマンド(と実際に時計で測った時間)では95分、clock()関数で測った プログラム全体の実行時間は1376秒(約23分)と誤差が出る状態にあります。 プログラムでclock()関数を使っているのはmain()だけです。 printf()内がおかしいのでしょうか? 詳しい方、回答よろしくおねがいします。 ↓プログラム #include<time.h> (中略) clock_t t1,t2,t3,t4; (中略) main() { struct zahyo P,Q; int a,b,prime,Ord,sec; scanf("%d",&a); (中略) printf("Q.y = "); scanf("%d",&Q.y); t1=clock(); Ord=OrdCal(P,a,prime); t2=clock(); printf("Ord = %d\n",Ord); printf("OrdCal:%f(s)\n",(double)(t2-t1)/CLOCKS_PER_SEC); t3=clock(); PohlingBsgs(P,Q,a,prime,Ord); sec=secretkey(); t4=clock(); printf("secretkey=%d\n",sec); printf("Decipher:%f(s)\n",(double)(t4-t3)/CLOCKS_PER_SEC); printf("Total :%f(s)\n",(double)(t4-t1)/CLOCKS_PER_SEC); } 実行結果 Ordcal:74.170000(s) Decipher:1302.722704(s) Total :1376.902104(s) real 94m33.445s user 94m30.900s sys 0m0.980s

  • 秒数を数える(C言語)

    プログラム実行時に時間を数え始めて、100秒経過したらまた最初からプログラムを実行しようと考えています。(tcpdumpみたいなもの) まず、秒数を数えて出力するプログラムを作ってみたのですが、実行しても0.000000と出てしまい、数えることが出来ませんでした。 (例) #include<stdio.h> #include<time.h> void tekitou(); int main() { while(1) { /*無限ループ*/ tekitou(); } return 0; } void tekitou() { static time_t start; time_t last; start = clock(); last = clock(); printf("%f\n", (double)(last - start)/CLOCKS_PER_SEC); } OSはLinuxでコンパイラはgccです。よろしくおねがいします。

  • clock関数を利用した時間計測法について

    以下のソースコードについての質問です。 --- /* 文字列を1文字ずつ表示して後ろから1文字ずつ消去するのを繰り返す */ #include <time.h> #include <stdio.h> /*--- xミリ秒経過するのを待つ ---*/ int sleep(unsigned long x) { clock_t c1 = clock(), c2; do { if ((c2 = clock()) == (clock_t)-1) /* エラー */ return (0); } while (1000.0 * (c2 - c1) / CLOCKS_PER_SEC < x); return (1); } --- このコード中の while (1000.0 * (c2 - c1) / CLOCKS_PER_SEC < x); の箇所で、整数の 1000 ではなく、実数の 1000.0 を使う意味(メリット)は オーバーフロー対策の他に何かありますか? ありましたら教えてください。 また、整数の1000に比べ実数の1000.0を含む計算(浮動小数点演算)に 極端に時間がかかる環境の場合、 実数を使う方がsleep関数の精度が劣るデメリットがあると思いますが、 その他に実数を使う場合のデメリットはありますか? ありましたら教えてください。 (コードにおいて、clock_t型はunsignedと同義の場合もあれば signed long intと同義の場合もあると思いますが、どれもありうる(処理系依存)と考えてください。 CLOCKS_PER_SECも1000や1000000の場合もあると思いますが、どれもありうる(処理系依存)と考えてください。)

  • 素因数分解のプログラムを作成しました。

    素因数分解のプログラムを作成しました。 なぜか11桁を超えた場合、正しく表示されません!! アドバイス等お願いします。 あと、処理時間も組んでみましたがこちらもうまくいきません。 改善をお願いしますm(_ _)m #include<stdio.h> #include<time.h> void fanction(int); void main(void) { int n; clock_t start_time, end_time; printf("整数を入力してください。\n"); scanf("%d",&n); start_time = clock(); fanction(n); end_time = clock(); printf("\n\n処理時間:%.3f秒\n",(double)(end_time - start_time) / CLOCKS_PER_SEC); return 0; } void fanction(int n) { int m; char c='='; for(m=2;n != 1;m++) { while(n%m == 0) { n = n/m; printf("%c%d",c,m); c='*'; } } }

  • 時間を経過させる関数

    この関数は引数xに1000を渡すと1秒の経過をさせる 関数です。 int sleep(unsigned long x) { clock_t c1 = clock(),c2; do { if((c2 = clock()) == (clock_t)-1) return 0; }while(1000.0*(c2-c1)/CLOCKS_PER_SEC<x); return 1; } 質問は3つです。 (1) if((c2 = clock()) == (clock_t)-1) return 0; ・clock()を呼び出し、その結果をc2に代入する。c2が-1だったら、returnする。返却値は0を返す。 つまり、時間の経過中にエラーが起きたら値を返すというものです。 質問としては、「(clock_t)-1」の意味です。「clock_t型から-1を引く?」なぜ-1と等しいのでしょうか? (2) while(1000.0*(c2-c1)/CLOCKS_PER_SEC<x); この文なのですが、なぜc2からc1を引く理由としては ・c1は関数を呼び出した時点の時間であり0秒固定。 ・c2に関しては「上記の不等式が不成立になるまで経過する時間」 と考えてよろしかったでしょうか? (3) また、上記の文の不等式の右辺のxは単位がミリ秒なので、不成立になるには、不等 式の左側は「関数呼び出しから現在までの経過時間(ミリ秒)」になるはずです。 左辺は最初に(c2-c1)を1000倍をしてそこからCLOCKS_PER_SECという 一秒あたりのクロック数(1000)を割っているのでc2やc1は最初から ミリ秒の単位がclock()で渡されるということなのでしょうか? お手数ですがよろしくお願いします。

  • clock関数での経過時間計測

    clock関数でプログラムの時間を計測しようと思っているのですがうまくいきません。 ----------------------------- clock_t start,end; start = clock(); (処理) end = clock(); printf("かかった時間:%f",(double)(end-start)/CLOCKS_PER_SEC); ----------------------------- 上のようにしているのですが、実行結果は0.00000秒と出てしまいます。処理のところは足し算を何題か出題し解答を入力し正解したら次の問題というようなことをしています。 確認のためstartにclock()を代入した後とendに代入したあとでprintfでstartとendを出力してみましたが、どちらの値も10.00000で同じ値となっています。0秒になるのはこれのせいだと思うのですが、どうして同じ値になるのでしょうか?

  • ソートの時間計算について

    ソートの時間計測について以下のようなプログラムを作成したのですが、ソートはうまく動きますが何度試しても処理時間が0.00000秒となってしまいます。どのように改良すればこのような問題を解決できるのでしょうか。ご回答よろしくお願いいたします。 #include <stdio.h> #include <time.h> #define SIZE 100 void swap(int data[], int s, int t){ int tmp = data[s]; data[s] = data[t]; data[t] = tmp; } void Bsort(int data[], int size) { int i, j; for(i=1; i<size; i++){ for(j=(size-1); j>0; j--){ if(data[j] < data[j-1]){ swap(data, j, j-1); } } } } void Ssort(int data[], int size){ int i, j, k, tmp; for(i=1; i<size; i++){ k = data[i-1]; for(j=i; j<size; j++){ if(k>data[j]){ tmp = k; k = data[j]; data[j] = tmp; } } tmp = k; k = data[i-1]; data[i-1] = tmp; } } void printArray(int ar[], int size) { int i; for (i = 0; i < size; i++) printf("%4d", ar[i]); printf("\n"); } int main(void) { int i, x; int data[SIZE]= {412, 54, 595, 329, 24, 488, 313, 272, 129, 210, 670, 516, 342, 541, 491, 640, 167, 117, 726, 206, 474, 762, 153, 292, 1000, 607, 151, 661, 93, 270, 737, 531, 641, 548, 299, 287, 547, 394, 550, 475, 443, 261, 707, 503, 403, 739, 226, 646, 778, 588, 427, 169, 477, 572, 413, 300, 88, 321, 55, 779, 542, 680, 211, 273, 288, 276, 405, 307, 424, 668, 756, 255, 190, 449, 35, 435, 91, 486, 58, 408, 4, 63, 534, 330, 701, 65, 256, 311, 586, 404, 459, 254, 291, 333, 42, 343, 418, 512, 164, 56}; clock_t t1,t2; printf("番号を入力してください。\n1,Bubble Sort\n2,Selection Sort\n"); scanf("%d", &x); switch(x){ case 1: printf("before:"); printArray(data, SIZE); t1 = clock(); Bsort(data, SIZE); t2 = clock(); printf(" after:"); printArray(data, SIZE); printf("処理時間:%f[ms]¥n", (double)(t2 - t1) / CLOCKS_PER_SEC); break; case 2: printf("before:"); printArray(data, SIZE); t1 = clock(); Ssort(data, SIZE); t2 = clock(); printf(" after:"); printArray(data, SIZE); printf("処理時間:%f[ms]¥n", (double)(t2 - t1) / CLOCKS_PER_SEC); break; } return 0; }

  • プログラムが3日目以降から調子が悪くなる

    C言語を用いてある測定装置のデータを5秒おきに取得するプログラムを作成したのですが、3日11時間14分(61,128回目のループ)を過ぎると取得する時間が15秒後に一回になっていました。おそらくループが原因だと思うのですが自分で解決できなくて困っています。 ループの入り口は for(p=1;p<=loop;p++){ でpの型はlong型です。 5秒間に1つずつpの値は増えていくのですが、long型なので大きさは十分だと思います。 5秒間待つループは while((((clock()-start1)/ CLOCKS_PER_SEC ) % TIME )!= 0 ) { } // TIME=5 としてあり、start1には一番最初のループの前で取得した時間データが入っています。

専門家に質問してみよう