我正在開發一個簡單的軟件來檢查我是否能夠使用我研究的POSIX定時器和信號進行編程。POSIX定時器和POSIX信號處理
我試圖做一個簡單的程序,啓動一個定時器,發出的信號一定量的納秒
下面的程序無法正常工作,所以我寫了一篇關於我的代碼一些評論,所以你可以檢查我正確研究與否。 您可以在頁面底部找到完整的代碼清單。
像
prinf("1\n")這樣的各種打印件將檢查程序提前退出的位置。 我把
struct sigevent sigeventStruct作爲定時器生成的到期事件的結構。 第一個參數設置爲SIGEV_SIGNAL,因此這是它將發出的信號種類。 /// 您可以在代碼清單中讀取的各種memset都是零初始化結構。
if(timer_create(_POSIX_MONOTONIC_CLOCK, &sigeventStruct, &timer1) == -1)
是創建一個POSIX計時器。 POSIX MONOTONIC CLOCK是一種定時器,& sigeventStruct是指向描述它是如何由定時器過期生成的事件的結構的指針。 & timer1是指向特定計時器名稱的指針。
if(timer_settime(timer1, NULL, &tempoIniziale, &tempoFinale) == -1)
用這個程序,定時器是裝備的,所以你可以使它生成到期。 timer1是定時器的名稱,0是標誌。 GAPIL書說:<> & tempoIniziale和& tempoFinale是指向itimerspec結構的指針。我還沒有很好地理解& old_timer的含義。在GAPIL書,你可以閱讀:將作爲參數傳遞 <>
struct sigaction, oldSigAzione
的sigaction結構針對sigaction POSIX信號處理
sigaction (SIGEV_SIGNAL, NULL, &oldSigAzione)
SIGEV_SIGNAL是一種信號,它具有處理,空IS在那裏它可以放置一個指向const struct sigaction的指針,& oldSigAzione是指向我前面提到的sigaction結構的指針。在這裏,我還沒有理解這兩個指向sigaction結構的指針之間的區別。
我的問題是: 爲什麼程序在打印printf(「19 \ n」)的19號之前退出;爲什麼不執行printf(「Timer scaduto \ n」);裏面的函數void termination_handler(int signum)?
這裏我的代碼:
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <time.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/fcntl.h>
#include <sys/wait.h>
#include <stdbool.h>
void termination_handler(int signum)
{
printf("Timer scaduto\n");
}
int main()
{
printf("Start\n");
printf("1\n");
struct sigevent sigeventStruct; // sigevent struct that will be used by timer1 timer
printf("2\n");
memset(&sigeventStruct, 0, sizeof sigeventStruct); // zero initialize struct
printf("3\n");
sigeventStruct.sigev_notify = SIGEV_SIGNAL; // kind of notification of timer1 expiration
printf("4\n");
sigeventStruct.sigev_signo = 10;
printf("5\n");
timer_t timer1; // create a timer identifier
printf("6\n");
if(timer_create(_POSIX_MONOTONIC_CLOCK, &sigeventStruct, &timer1) == -1)
{
printf("Errore timer_create: %s\n", strerror(errno));
}
printf("7\n");
struct itimerspec tempoIniziale;
printf("8\n");
memset(&tempoIniziale, NULL, sizeof tempoIniziale); // zero initialize struct
printf("9\n");
tempoIniziale.it_value.tv_nsec = 100000000;
//tempoIniziale.it_interval.tv_nsec = 10000;
printf("10\n");
if(timer_settime(timer1, 0, &tempoIniziale, NULL) == -1) // timer armed
{
printf("Errore timer_settime: %s\n", strerror(errno));
}
printf("11\n");
for(int i = 0; i< 10; i++)
{
printf("ciclo %d\n", i);
}
struct sigaction oldSigAzione;
printf("12\n");
memset(&oldSigAzione, 0, sizeof oldSigAzione);
printf("13\n");
oldSigAzione.sa_handler = termination_handler;
printf("14\n");
sigemptyset (&oldSigAzione.sa_mask);
printf("15\n");
oldSigAzione.sa_flags = 0;
printf("16\n");
sigaction (SIGEV_SIGNAL, NULL, &oldSigAzione);
printf("17\n");
if(oldSigAzione.sa_handler == SIG_IGN)
{
printf("Segnale ignorato\n");
}
printf("18\n");
for(int i = 0; i < 1000000000000; i++)
{
}
printf("19\n");
printf("number of expirations %d\n", timer_getoverrun(timer1));
return 0;
}
空的for循環不是延遲的方式。一個現代編譯器將它編譯成完全沒有代碼。試試'sleep' ... –
另外,'printf'不是異步信號安全的。你不能在信號處理程序中使用它,除非你避免在代碼中可能被信號中斷的所有對異步信號不安全函數的調用。 –