Linux でタイマーを実装する 3 つの簡単な方法

目次

1. sleep() と usleep()

1.スリープ()

2.usleep()

3. ミリ秒の遅延

2. シグナルとアラーム()

3.選択

4. いくつかの結論


1. sleep() と usleep()

        利点は、シンプルで便利で、直接呼び出すことができることですが、欠点も明らかで、精度が十分ではなく、特にシステム負荷が比較的大きい場合、タイムアウト現象が発生します。

1.スリープ()

#include <unistd.h>

unsigned int sleep(unsigned int 秒);

機能: 指定した秒数の間、実行を一時停止します。

        sleep() は第 2 レベルまでしか正確ではありません。sleep() はシステム コールではなく、sleep() はライブラリ関数に実装されており、alarm() を使用してアラーム時刻を設定し、sigsuspend() を使用してシグナル SIGALARM でプロセスを一時停止します。sleep() は、パラメータ秒で指定された時間が経過するか、シグナルによって中断されるまで、現在のプロセスを一時停止します。

2.usleep()

#include <unistd.h>

void usleep(int micro_秒);

機能: 一定時間プロセスを一時停止します。単位はマイクロ秒 (100 万分の 1) です。

        時間単位がマイクロ秒である点を除けば、使用方法は sleep() と似ています。ただし、実装は異なります。sleep はアラームとともに実装されているため、時間単位は s で、usleep の時間単位は us です。アラームによって実装されていることは間違いないため、実装は異なりますが、それらはすべて Linux によって使用されます。および window sleep と usleep の両方が unistd.h の下で定義されているため、この下では使用できません。

        一般に、遅延時間が秒オーダーの場合は、可能な限り sleep() 関数を使用します。遅延時間が数十ミリ秒(1ms = 1000us)以下の場合は、可能な限り usleep() 関数を使用してください。この方法でのみ、CPU 時間を最適に利用できます。

3. ミリ秒の遅延

        Linux では既製のミリ秒レベルの遅延がないため、ここでは単純に自分で遅延を作成できます。

#include <unistd.h>

void msleep(unsigned long     ms)
{
    struct timeval        tv;
    tv.tv_sec = ms/1000;
    tv.tv_usec = (ms%1000)*1000;

    select(0, NULL, NULL, NULL, &tv);
}

2. シグナルとアラーム()

        signal 関数を使用して SIGALRM の処理機能を設定し、alarm() を使用して SIGALRM を定期的に送信することで実現します。  

#include <stdio.h>
#include <signal.h>
#include <unistd.h>

int alarm_flag=1;

void timer(int sig)
{
    if(SIGALRM == sig)
    {
        alarm_flag = 1;
    }
    return;
}

int main()
{
    signal(SIGALRM, timer);
    
    while( alrm_flag )
    {
        alarm_flag = 0;

        printf("hello\n");
        alarm(5);
     }

    return 0;
}

#include <unistd.h>

unsigned int アラーム (unsigned int 秒);        

機能: 信号送信目覚まし時計を設定します。

        alarm() は、アラーム クロック関数とも呼ばれます。alarm() 関数の主な機能は、シグナル送信アラーム クロックを設定すること、つまり、秒数が経過した後に現在のプロセスにシグナル SIGALRM が送信されるように設定することです。パラメータ秒で指定します。シグナル SIGALARM の処理関数が設定されていない場合、alarm() はデフォルトでプロセスを終了します。パラメータ秒が 0 の場合、以前に設定した目覚まし時計はキャンセルされ、残り時間が返されます。

        PS: プロセスに設定できるアラーム時間は 1 つだけです。アラームを呼び出す前にアラーム時間が設定されている場合、以前のアラーム時間は新しい値に置き換えられます。

3.選択

#include <sys/select.h>

#include <sys/time.h>

#include <sys/types.h>

#include <unistd.h>

int select(int n, fd_set *readfds, fd_set *writefds, fd_set *Exceptfds, struct timeval * timeout);

機能: ファイル記述子のステータス変化を待つために使用されます。パラメータ n は、最大のファイル記述子に 1 を加えたものを表し、パラメータ readfds、writefds、およびExceptfds は記述子グループと呼ばれ、記述子の読み取り、書き込み、または例外ステータスを返すために使用されます。

         select 関数のパラメータや機能についてはここでは詳しく紹介しませんので、興味があれば調べてください。ここでタイマーを実装したい場合は、最初のパラメータを 0 に設定し、中央の 3 つのファイル記述子セットを NULL に設定し、5 番目のパラメータは時間構造です。主にこのパラメータを使用し、希望する値に設定します。タイミング周波数は次のとおりです。大丈夫。

        timeout は select() の待ち時間を設定する構造体 timeval であり、その構造体は次のように定義されています。

構造体 timeval

{

        time_t tv_sec;

        time_t tv_usec;
};

#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

void timer_s(unsigned long    s, unsigned long     us)
{
    struct timeval        tv;

    tv.tv_sec = s;
    tv.tv_usec = us;

    select(0, NULL, NULL, NULL, &tv);
}

int main()
{
    while(1)
    {
        printf("hello\n");
        timer_s(3, 0);
    }

    return 0;
}

4. いくつかの結論

        誰もが自分のニーズに応じて選択します。これはインターネットから拾った画像です。原文へのリンクは次のとおりです。

Linux でのスリープ、usleep、nanosleep、ポーリングおよび選択のさまざまなスリープ方法https://mp.weixin.qq.com/s?src=11×tamp=1680196399&ver=4438&signature=LzDVJT7uLU7DuxA6qxK8Sm4FqjJw8G347mhB56nkDIb5R2XQs ifqz-NFi1nmisdV YxrrRNgLVKIJqjN4koJ59oTtTBWunbaWVMV7u6dNydmBRf-DA9aR6yVNKkbJF*oI&new=1

おすすめ

転載: blog.csdn.net/qq_51368339/article/details/129870386