Windows system >> Windowsの知識 >  >> Linuxシステムチュートリアル >> Linuxチュートリアル >> Linuxでの正確なタイミングと休止状態

Linuxでの正確なタイミングと休止状態

  

Linuxで提供されている休止状態機能はsleep()ですが、休止状態を提供するのは数秒しかありません。小さな時間分解能の睡眠?

私が知っている方法は2つあります。以下でそれらを別々に紹介します。

最初の方法はタイマーを使うことですLinuxで提供されているタイマー関数は次のとおりです:

int setitimer(int which、const struct itimerval * value、struct itimerval * ovalue);タイマーの種類Linuxは3種類のタイマーを提供します:

TIMER_REAL:正確なタイマー、タイムアウトはSIGALRMシグナルを発行します; TIMER_VIRTUAL:仮想タイマー、プロセス時間のみ、したがってプロセス実行時間に応じて変化し、正確なタイミングを達成できません。タイムアウトはSIGVTALRMシグナルを送信します; TIMER_PROF:あらすじタイマー、それはプロセス時間とシステム時間に従って変化します、正確なタイミングを達成することができません、タイムアウトSIGPROFシグナル;

プロセスで設定されたタイマーが発行されますシグナルは、プロセスがタイマータイムアウトからシグナルを受信したため、デフォルトのアクションが終了します。

値はタイマー時間を設定するためのもので、関連する構造は次のとおりです。

struct itimerval {struct timeval it_interval; struct timeval it_value;}; struct timeval {long tv_sec; long tv_usec;}; it_interval指定間隔Time、it_valueは初期タイミング時間を指定します。 it_valueのみが指定されている場合は1回実行され、同時にit_intervalが指定されている場合は、タイムアウト後にit_valueがit_intervalに再初期化され、両方がクリアされている場合はタイマーがクリアされます。

tv_secは第2レベルの精度を提供し、tv_usecはマイクロ秒の精度を提供し、firstの値で1s = 1000000usに注意を払います。

ovalueは、NULLのまま、前の値を保存するために使用されます。

setitimer()が提供するタイマーで眠っているのなら、単にpause()でwait timerシグナルを一時停止してください。 2番目の方法は、select()を使用して正確なタイミングと休止状態を提供することです。

int select(int n、fd_set * readfds、fd_set * writefds、fd_set * exceptfds、struct timeval * timeout); nはモニタリングを意味します。ファイル記述子の範囲(通常はselect()のfd + 1、readfds、writefds、およびexceptfds)は、読み取り、書き込み、および例外のファイル記述子セットであり、timeoutはタイムアウトです。

ファイルディスクリプタセット操作に使用できるマクロは次のとおりです。

FD_CLR(int fd、fd_set * set); Clear fdFD_ISSET(int fd、fd_set * set); Test fd Set FD_SET(int fd、fd_set * set); Set fdFD_ZERO(fd_set * set);ディスクリプタセットをクリアするファイルディスクリプタの状態を気にしないので、現時点ではこれらのマクロは必要ありません。タイムアウトそのため、タイムアウト時間を指定するだけで、readfds、writefds、exceptfdsをNULLに設定する必要があります。 nに関しては気にすることはできないので、あなたはそれを任意の負でない値に設定することができます。実装コードは次のとおりです。

int usSleep(long us){struct timeval tv; tv.tv_sec = 0; tv.tv_usec = us; return select(0、NULL、NULL、NULL、& tv);}おお、どうやって、それはとても簡単ですか?

結論:setitimer()とselect()はプロセスの正確なスリープを実現することができますこの記事ではそれらについて簡単に紹介し、select()に基づく簡単な実装を示します。 setitimerの使用はお勧めできません。Linuxシステムの1つには限られた数のタイマー(各プロセスに最大3つの異なるタイプのタイマーがある)があり、setitimer()にはselect()が単純ではないからです。

2008年9月12日に編集------------------------------------ -------------------------------

33とffff、msとusエラーのフィードバックをありがとう修正されました。弟は学習が苦手なので、みんなの誤解を許しますし、あなたの意見も歓迎し、一緒に進歩していきます。私は他のスリープ機能を追加したいので、私はタイトルを変更しました、オリジナルのタイトルは現在のコンテンツには適していません。まず、ffffが言っているように、usleep()を使って2番目のプロセス以下にスリープさせることができます。

int usleep(unsigned long usec); sleep()と同様に、プロセスがシグナルを受け取ると戻ります。しかし、Linuxのマニュアルでは、sleep()のようにスリープなしの秒数を返さず、-1を返してerrnoをEINTRに設定しています。 uClibcの実装は次のとおりです。

int usleep(__useconds_t usec){const struct timespec ts = {.tv_sec =(long int)(usec /1000000)、.tv_nsec =(long int)(usec%1000000)*表示されているusleep()は、nanosleep()関数によって内部的に実装されています次に、nanosleep()関数について説明します。また、select()を使った次のような実装も見ました。これは、前述のメソッドもサポートしています。

int usleep(符号なしlong usec){static struct {/* `timeval '* /long tv_sec; /*秒* /long tv_usec; /* microsecs * /} delay; /* _select()timeout * /delay.tv_sec = usec /1000000L; delay.tv_usec = usec%1000000L; return select(0、(long *)0、(long *)0、(long *)0、& delay);}次に戻るnanosleep()を見てください。 Nanosleep()は、ナノ秒(1/1000 000 000)レベルの睡眠を達成できるので、usleep()よりも正確です。しかし、あなたのCPUはそのような高解像度をサポートするために少なくとも1GHzを必要とします。 nanosleep()のプロトタイプは次のとおりです。

int nanosleep(const struct timespec * rqtp、struct timespec * rmtp);最初のパラメータはスリープ時間を指定し、2番目のパラメータはシグナルが中断されるとスリープ状態に戻ります。十分な時間があるので、timespec構造体は次のようになります。

struct timespec {time_t tv_sec; /* seconds * /long tv_nsec; /* nanoseconds * /}; tv_sevは秒数を指定するために使用され、tv_nsecはナノ秒数を指定するために使用されます。上記の他の関数とは異なり、nanosleep()はtimespec構造体の両方のメンバーに使用されるため、tv_nsecに999 999 999より大きな値を指定することはできません。 tv_secを与えます。 sleep()とalarm()は残り時間を返し、usleep()、nanosleep()とselect()は-1を返します。

Copyright © Windowsの知識 All Rights Reserved