ホームページ  >  記事  >  システムチュートリアル  >  最も強力なタイマー インターフェイスは POSIX クロック シリーズから来ていることをご存知ですか?

最も強力なタイマー インターフェイスは POSIX クロック シリーズから来ていることをご存知ですか?

WBOY
WBOY転載
2024-03-10 11:40:031109ブラウズ

最も強力なタイマー ソケットは、POSIX クロック シリーズから提供されます。タイマーの作成、初期化、および削除のアクションは、timer_create() (タイマーの作成)、timer_settime() (タイマーの初期化)、デバイスの 3 つの異なる関数に分割されます。 timer_delete (破棄)。

タイマーを作成する:

リーリー

プロセスは timer_create() を呼び出すことで特定のタイマーを作成できます。タイマーは各プロセスに固有であり、フォーク時に継承されません。 Clock_id はタイマーがどのクロックに基づいているかを示し、*timerid は作成されたタイマーの ID をロードします。この関数はタイマーを作成し、その ID を timerid が指す場所にロードします。パラメータ evp は、タイマーが期限切れになったときに生成される非同期通知を指定します。 evp が NULL の場合、タイマーの期限切れによりデフォルトの信号が生成されます。CLOCK_REALTIMER の場合、デフォルトの信号は SIGALRM です。デフォルトのシグナル linux 以外のシグナルを生成したい場合、プログラムは evp->sigev_signo を目的のシグナル番号に設定する必要があります。 structsigevent 構造体のメンバー evp->sigev_notify は、タイマーが期限切れになったときに実行する必要があるアクションを記述します。通常、このメンバーの値は SIGEV_SIGNAL で、タイマーが期限切れになったときにシグナルが生成されることを示します。プログラムは、メンバー evp->sigev_notify を SIGEV_NONE に設定して、タイマーの期限切れ時にシグナルが生成されないようにすることができます。

複数のタイマーが同じシグナルを生成する場合、ハンドラーは evp->sigev_value を使用して、どのタイマーがシグナルを生成したかを判断できます。これらの関数を実装するには、シグナルのハンドラーをインストールするときに、プログラムで structsigaction のメンバー sa_flags 内の識別子 SA_SIGINFO を使用する必要があります。

Clock_id の値は次のとおりです:

リーリー

evp->sigev_notify を次の値に設定して、タイマーの期限切れ後の動作をカスタマイズします。

タイマーを開始します:

timer_create() によって作成されたタイマーは開始されていません。有効期限と開始クロック期間を関連付けるには、timer_settime() を使用します。

リーリー

リーリー

settimer() と同様に、it_value は現在のタイマーの有効期限を指定するために使用されます。タイマーが期限切れになると、it_value の値が it_interval の値に更新されます。 it_interval の値が 0 の場合、タイマーはインターバル タイマーではなく、it_value の期限が切れると開始されていない状態に戻ります。 timespec の構造はミリ秒レベルのコード レートを提供します:

リーリー

flags の値が TIMER_ABSTIME の場合、value で指定された時間値は絶対値に解析されます (この値のデフォルトの解析方法は現在時刻を基準とした相対値です)。この変更された動作により、現在の時刻の取得、現在の時刻と将来の望ましい時刻との相対的な差の計算、およびタイマーの開始中に競合状態が発生するのが防止されます。

定时器程序设计实验报告_linux 定时器程序_定时器程序编写

ovalue の値が NULL でない場合、前回のタイマー有効期限は、指定された itimerspec に保存されます。タイマーが以前に開始されていない場合、この構造体のすべてのメンバーは 0 に設定されます。

アクティブなタイマーの残り時間を取得します:

リーリー

タイマーのオーバーラン実行回数を取得します:

有可能一个定时器到期了,而同一定时器上一次到期时形成的讯号还处于挂起状态。在这些情况下,其中的一个讯号可能会遗失。这就是定时器超限。程序可以通过调用timer_getoverrun来确定一个特定的定时器出现这些超限的次数。定时器超限只能发生在同一个定时器形成的讯号上。由多个定时器linux 定时器程序,甚至是这些使用相同的时钟和讯号的定时器,所形成的讯号就会排队而不会遗失。

<span style="font-family:SimSun;font-size:18px;color:#ff0000">int timer_delete (timer_t timerid);</span>

执行成功时,timer_getoverrun()会返回定时器初次到期与通知进程(比如通过讯号)定时器已到期之间额外发生的定时器到期次数。举例来说linux 定时器程序,在我们之前的事例中,一个1ms的定时器运行了10ms,则此调用会返回9。假如超限运行的次数等于或小于DELAYTIMER_MAX,则此调用会返回DELAYTIMER_MAX。

执行失败时,此函数会返回-1并将errno设定会EINVAL,这个惟一的错误情况代表timerid指定了无效的定时器。

删掉一个定时器:

<span style="font-family:SimSun;font-size:18px;color:#ff0000">int timer_delete (timer_t timerid);</span>

一次成功的timer_delete()调用会销毁关联到timerid的定时器而且返回0。执行失败时,此调用会返回-1并将errno设定会EINVAL,这个惟一的错误情况代表timerid不是一个有效的定时器。

例1:

voidhandle()

time_tt;

charp[32];

time(&t);

strftime(p,sizeof(p),"%T",localtime(&t));

printf("timeis%s/n",p);

intmain()

structsigeventevp;

structitimerspects;

timer_ttimer;

intret;

evp.sigev_value.sival_ptr=&timer;

evp.sigev_notify=SIGEV_SIGNAL;

evp.sigev_signo=SIGUSR1;

定时器程序设计实验报告_定时器程序编写_linux 定时器程序

signal(SIGUSR1,handle);

ret=timer_create(CLOCK_REALTIME,&evp,&timer);

if(ret)

perror("timer_create");

_sec=1;

_nsec=0;

_sec=3;

_nsec=0;

ret=timer_settime(timer,0,&ts,NULL);

if(ret)

perror("timer_settime");

while(1);

例2:

voidhandle(unionsigvalv)

時間_tt;

charp[32];

時間(&t);

strftime(p,sizeof(p),"%T",localtime(&t));

printf("%sthread%lu,val=%d,signalcaptured./n",p,pthread_self(),v.sival_int);

###戻る;###

intmain()

structsigeventevp;

構造的観点;

タイマー_tタイマー;

インレット;

memset(&evp,0,sizeof(evp));

定时器程序设计实验报告_linux 定时器程序_定时器程序编写evp.sigev_value.sival_ptr=&timer;

evp.sigev_notify=SIGEV_THREAD;

evp.sigev_notify_function=ハンドル;

evp.sigev_value.sival_int=3;//handle() としてのパラメータ

ret=timer_create(CLOCK_REALTIME,&evp,&timer);

if(ret)

perror("timer_create");

_秒=1;

_nsec=0;

_秒=3;

_nsec=0;

ret=timer_settime(タイマー,TIMER_ABSTIME,&ts,NULL);

if(ret)

perror("timer_settime");

while(1);

以上が最も強力なタイマー インターフェイスは POSIX クロック シリーズから来ていることをご存知ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はitcool.netで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。