Heim  >  Artikel  >  System-Tutorial  >  Wussten Sie, dass die leistungsstärkste Timer-Schnittstelle aus der POSIX-Uhrenserie stammt?

Wussten Sie, dass die leistungsstärkste Timer-Schnittstelle aus der POSIX-Uhrenserie stammt?

WBOY
WBOYnach vorne
2024-03-10 11:40:031110Durchsuche

Der leistungsstärkste Timer-Socket stammt aus der POSIX-Uhrenserie. Die Aktionen zum Erstellen, Initialisieren und Löschen eines Timers sind in drei verschiedene Funktionen unterteilt: timer_create() (Timer erstellen), timer_settime() (Timer initialisieren) und timer_delete (Zerstören). ).

Erstellen Sie einen Timer:

<span style="font-family:SimSun;font-size:18px;color:#ff0000">int timer_create(clockid_t clock_id, struct sigevent *evp, timer_t *timerid)</span>

Ein Prozess kann einen bestimmten Timer erstellen, indem er timer_create() aufruft. Der Timer ist für jeden Prozess einzigartig und wird beim Forken nicht vererbt. clock_id gibt an, auf welcher Uhr der Timer basiert, und *timerid lädt die ID des erstellten Timers. Diese Funktion erstellt den Timer und lädt seine ID in den Speicherort, auf den timerid zeigt. Der Parameter evp gibt die asynchrone Benachrichtigung an, die generiert werden soll, wenn der Timer abläuft. Wenn evp NULL ist, generiert der Timer-Ablauf ein Standardsignal. Für CLOCK_REALTIMER ist das Standardsignal SIGALRM. Wenn Sie ein anderes Signal als das Standardsignal-Linux generieren möchten, muss das Programm evp->sigev_signo auf die gewünschte Signalnummer setzen. Das Mitglied evp->sigev_notify in der Struktur structsigevent beschreibt die Aktion, die ausgeführt werden soll, wenn der Timer abläuft. Im Allgemeinen ist der Wert dieses Mitglieds SIGEV_SIGNAL, was angibt, dass ein Signal generiert wird, wenn der Timer abläuft. Das Programm kann das Mitglied evp->sigev_notify auf SIGEV_NONE setzen, um zu vermeiden, dass bei Ablauf des Timers ein Signal generiert wird.

Wenn mehrere Timer das gleiche Signal erzeugen, kann der Handler mithilfe von evp->sigev_value identifizieren, welcher Timer das Signal generiert hat. Um diese Funktionen zu implementieren, muss das Programm beim Installieren eines Handlers für das Signal den Bezeichner SA_SIGINFO im Mitglied sa_flags von structsigaction verwenden.

Der Wert von

clock_id lautet wie folgt:

struct sigevent
{
<span>	</span>int sigev_notify; //notification type
<span>	</span>int sigev_signo; //signal number
<span>	</span>union sigval sigev_value; //signal value
<span>	</span>void (*sigev_notify_function)(union sigval);
<span>	</span>pthread_attr_t *sigev_notify_attributes;
}
union sigval
{
<span>	</span>int sival_int; //integer value
<span>	</span>void *sival_ptr; //pointer value
}

Passen Sie das Verhalten nach Ablauf des Timers an, indem Sie evp->sigev_notify auf den folgenden Wert setzen:

Starten Sie einen Timer:

Der von timer_create() erstellte Timer wurde nicht gestartet. Um es mit einer Ablaufzeit und einer Startuhrperiode zu verknüpfen, verwenden Sie timer_settime().

<span style="font-family:SimSun;font-size:18px;color:#ff0000">int timer_settime(timer_t timerid, int flags, const struct itimerspec *value, struct itimerspect *ovalue);</span>

struct itimespec
{
struct timespec it_interval; 
struct timespec it_value; 
}; 

Genau wie settimer() wird it_value verwendet, um die aktuelle Ablaufzeit des Timers anzugeben. Wenn der Timer abläuft, wird der Wert von it_value auf den Wert von it_interval aktualisiert. Wenn der Wert von it_interval 0 ist, ist der Timer kein Intervall-Timer und kehrt in den nicht gestarteten Zustand zurück, sobald it_value abläuft. Die Struktur der Zeitspezifikation bietet eine Coderate auf Millisekundenebene:

struct timespec
{
time_t tv_sec;
long tv_nsec;
};

Wenn der Wert der Flags TIMER_ABSTIME ist, wird der durch value angegebene Zeitwert in einen absoluten Wert geparst (die Standard-Parsing-Methode für diesen Wert ist relativ zur aktuellen Zeit). Dieses geänderte Verhalten verhindert, dass beim Abrufen der aktuellen Zeit, beim Berechnen der relativen Differenz zwischen dieser Zeit und der gewünschten zukünftigen Zeit und beim Starten von Timern Rennbedingungen verursacht werden.

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

Wenn der Wert von ovalue nicht NULL ist, wird die vorherige Timer-Ablaufzeit in der bereitgestellten itimerspec gespeichert. Wenn der Timer vorher nicht gestartet wurde, werden alle Mitglieder dieser Struktur auf 0 gesetzt.

Rufen Sie die verbleibende Zeit eines aktiven Timers ab:

<span style="font-family:SimSun;font-size:18px;color:#ff0000">int timer_gettime(timer_t timerid,struct itimerspec *value);</span>

Ermitteln Sie die Anzahl der Nachläufe eines Timers:

有可能一个定时器到期了,而同一定时器上一次到期时形成的讯号还处于挂起状态。在这些情况下,其中的一个讯号可能会遗失。这就是定时器超限。程序可以通过调用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);

wenn(im Ruhestand)

perror("timer_settime");

while(1);

例2:

voidhandle(unionsigvalv)

time_tt;

charp[32];

time(&t);

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

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

zurück;

intmain()

structsigeventevp;

strukturelle Aspekte;

timer_ttimer;

intret;

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

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

evp.sigev_value.sival_ptr=&timer;

evp.sigev_notify=SIGEV_THREAD;

evp.sigev_notify_function=handle;

evp.sigev_value.sival_int=3;//作为handle()的参数

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

wenn(im Ruhestand)

perror("timer_create");

_sec=1;

_nsec=0;

_sec=3;

_nsec=0;

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

wenn(im Ruhestand)

perror("timer_settime");

while(1);

Das obige ist der detaillierte Inhalt vonWussten Sie, dass die leistungsstärkste Timer-Schnittstelle aus der POSIX-Uhrenserie stammt?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:itcool.net. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen

In Verbindung stehende Artikel

Mehr sehen