これをWordで検索する方法が正確にわからないので、何も見つけることができませんでした。
Cで時間遅延を実装する必要があります。
例えば、私は何かをしたいので、1分待ってから続けます。
それは理にかなっていますか?誰も私を助けることができますか?
標準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秒の解像度値を返すと仮定しています。それが規格によって義務付けられているとは思わないので、調整する必要があるかもしれません。
明確にするために、これはonlyISO C99でこれを行うことを認識している方法です(そして、質問には " C "は通常、ポータブルソリューションが望ましいことを意味しますが、もちろん、ベンダー固有のソリューションも提供されます。
より効率的な方法を提供するプラットフォームを使用している場合は、必ず使用してください。いくつかのコメントが示しているように、特定の問題があるかもしれませんCPU使用率とバッテリー寿命に関して、このようなタイトループを使用します。
適切なタイムスライシングOSは、フルタイムスライスを継続的に使用するタスクの動的優先度を下げることができますが、バッテリーの電力はより問題になる可能性があります。
ただし、Cはホスト環境のOSの詳細についてnothingを指定しており、この回答はISO CおよびISO Cのみに対するものです(したがって、sleep
、select
、Win32 API呼び出しなど。
POSIX sleep
は信号によって中断される可能性があることに注意してください。あなたがareその道を行く場合、あなたは次のようなことをする必要があります:
_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.
}
_
ほとんどのデスクトップシステムでこれを行う方法は次のとおりです。
#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
}
Waitloop変数は微調整する必要があります。これらは私のコンピューターにかなり近い動作をしましたが、周波数スケールの問題により、現代のデスクトップシステムでは非常に不正確になります。したがって、金属にむき出しになっていて、そのようなことをしていない限り、そこでは使用しないでください。
sleep(3)manページ または スリープ用のMSDN を確認してください
多くの実装には time
関数があり、現在の時刻をsecondsで返しますが、すべての実装がno保証である(たとえば、secondsではなくmillisecondsを返す場合があります)。そのため、よりポータブルなソリューションは、 difftime
関数を使用することです。
difftime
は、2つのtime_t
値間の時間差をsecondsで返すために、C標準によって保証されています。そのため、C標準のすべての準拠実装で実行されるポータブル時間遅延関数を作成できます。
#include <time.h>
void delay(double dly){
/* save start time */
const time_t start = time(NULL);
time_t current;
do{
/* get current time */
time(¤t);
/* break loop when the requested number of seconds have elapsed */
}while(difftime(current, start) < dly);
}
time
およびdifftime
関数の注意点の1つは、C標準が粒度を指定しないことです。ほとんどの実装の粒度はone secondです。これは数秒続く遅延に対しては問題ありませんが、遅延関数は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
関数の粒度は実装に任されます。たとえば、microsecondsの解像度を持つclock_t
の32ビット値を持つマシンは、2147秒(約36分)後にclock
によって返される値をラップする可能性があります。
したがって、少なくとも1秒持続する遅延にはtime
およびdifftime
遅延関数の実装を使用し、持続する遅延にはclock
実装を使用することを検討してください1秒未満。
最後の注意事項:clock
は、calendar timeではなく、processor timeを返します。 clock
は、実際の経過時間と一致しない場合があります(プロセスがスリープする場合など)。
1分の遅延の場合、sleep()
が適切な選択です。
いつか、1秒未満の遅延で一時停止する場合は、poll()
をタイムアウトで考慮することをお勧めします。
どちらもPOSIXです。
sleep(int number_of_seconds)
を試してください
sleep(int)
は良い遅延として機能します。少しの間:
//Doing some stuff...
sleep(60); //Freeze for A minute
//Continue doing stuff...
C標準ライブラリにはsleep()
関数はありませんが、POSIXにはいくつかのオプションがあります。
POSIX関数 sleep()
(unistd.h)は、スリープに必要な秒数の_unsigned int
_引数を取ります。これは標準ライブラリ関数ではありませんが、広く利用可能であり、glibcは_--std=c11
_のようなより厳密な設定でコンパイルする場合でもサポートするようです。
POSIX関数 nanosleep()
(time.h)は、timespec
構造体への2つのポインターを引数として取り、スリープ期間をより細かく制御します。最初の引数は遅延時間を指定します。 2番目の引数がNULLポインターでない場合、呼び出しがシグナルハンドラーによって中断された場合の残り時間を保持します。
nanosleep()
関数を使用するプログラムは、コンパイルするために feature test macro を含める必要がある場合があります。 _gcc -std=c11 -Wall -Wextra -Wpedantic
_の典型的なコンパイラー呼び出しを使用すると、機能テストマクロがないと、次のコードサンプルはLinuxシステムでコンパイルされません。
POSIXには、かつてマイクロ秒単位でスリープ期間を指定する_useconds_t
_引数を取る usleep()
関数(unistd.h)がありました。この関数は、厳密なコンパイラ設定で使用する場合、機能テストマクロも必要としました。残念ながら、usleep()
はPOSIX.1-2001で廃止されたため、使用すべきではありません。 nanosleep()
の代わりにusleep()
を使用することをお勧めします。
_#define _POSIX_C_SOURCE 199309L // feature test macro for nanosleep()
#include <stdio.h>
#include <unistd.h> // for sleep()
#include <time.h> // for nanosleep()
int main(void)
{
// use unsigned sleep(unsigned seconds)
puts("Wait 5 sec...");
sleep(5);
// use int nanosleep(const struct timespec *req, struct timespec *rem);
puts("Wait 2.5 sec...");
struct timespec ts = { .tv_sec = 2, // seconds to wait
.tv_nsec = 5e8 }; // additional nanoseconds
nanosleep(&ts, NULL);
puts("Bye");
return 0;
}
_
timer
ですか?
WIN32の場合 http://msdn.Microsoft.com/en-us/library/ms687012%28VS.85%29.aspx
// xミリ秒遅延するANSI Cメソッドを提供します
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void delayMillis(unsigned long ms) {
clock_t start_ticks = clock();
unsigned long millis_ticks = CLOCKS_PER_SEC/1000;
while (clock()-start_ticks < ms*millis_ticks) {
}
}
/*
* Example output:
*
* CLOCKS_PER_SEC:[1000000]
*
* Test Delay of 800 ms....
*
* start[2054], end[802058],
* elapsedSec:[0.802058]
*/
int testDelayMillis() {
printf("CLOCKS_PER_SEC:[%lu]\n\n", CLOCKS_PER_SEC);
clock_t start_t, end_t;
start_t = clock();
printf("Test Delay of 800 ms....\n", CLOCKS_PER_SEC);
delayMillis(800);
end_t = clock();
double elapsedSec = end_t/(double)CLOCKS_PER_SEC;
printf("\nstart[%lu], end[%lu], \nelapsedSec:[%f]\n", start_t, end_t, elapsedSec);
}
int main() {
testDelayMillis();
}
単純にdelay()関数を呼び出すことができます。したがって、プロセスを3秒で遅延させたい場合は、delay(3000)を呼び出します...
確実に待機し、決して中断されない場合は、POSIXでスリープを使用するか、Windowsでスリープを使用します。 POSIXスリープでは秒単位の時間がかかるため、時間を短くしたい場合は、マイクロ秒を使用するusleep()
などの種類があります。 Windowsでのスリープには数ミリ秒かかりますが、それより細かい粒度が必要になることはまれです。
しばらく待機したいが、おそらく緊急の場合に割り込みを許可したい場合があります。スリープはシグナルによって中断される可能性がありますが、この場合はより良い方法があります。
したがって、実際には、イベントで待機するか、タイムアウトを伴う条件変数であることが実際にわかっています。
Windowsでは、呼び出しはWaitForSingleObject
です。 POSIXでは、pthread_cond_timedwait
。
Windowsでは、WaitForSingleObjectEx
を使用することもできます。その後、QueueUserAPC
を呼び出すことにより、キューに入れられたタスクで実際にスレッドを「中断」できます。 WaitForSingleObject(Ex)は、終了した理由を特定するコードを返すため、「タイムアウト」ステータスが返されたときに、実際にタイムアウトしたことがわかります。終了したいときに待機するイベントを設定します。
pthread_cond_timedwait
条件変数のブロードキャストを通知できます。 (複数のスレッドが同じスレッドで待機している場合、それらをすべて起動するためにブロードキャストする必要があります)。ループするたびに、状態を確認する必要があります。スレッドは現在の時刻を取得して、経過したかどうかを確認したり、何らかの条件が満たされているかどうかを確認して、何をすべきかを判断したりできます。何らかの種類のキューがある場合は、確認できます。 (スレッドは、条件変数で待機するために使用されるmutexを自動的にロックするため、条件をチェックするときに、そのスレッドにアクセスするだけです)。