gpt4 book ai didi

c - POSIX 计时器和 POSIX 信号处理

转载 作者:太空宇宙 更新时间:2023-11-04 01:12:33 27 4
gpt4 key购买 nike

我正在开发一个简单的软件来检查我是否能够使用我研究过的 POSIX 定时器和信号进行编程。

我正在尝试做一个简单的程序来启动计时器并在一定的纳秒内发出信号

下面的程序运行得不好,所以我写了一些关于我的代码的评论,这样你就可以检查我是否正确学习了。您可以在页面底部找到完整的代码 list 。

各种打印像

prinf("1\n")
are to check where the program exits prematurely.I putted
struct sigevent sigeventStruct
as structure for expirations events generated by the timer.First parameter is setted to SIGEV_SIGNAL so this is the kind of signal it will emit. ///The various memset you can read in code listing are to zero initialized structures.

if(timer_create(_POSIX_MONOTONIC_CLOCK, &sigeventStruct, &timer1) == -1)

is to create a POSIX timer. POSIX MONOTONIC CLOCK is the kind of timer, &sigeventStruct is the pointer to the structure that describes how it is the event generated by the timer expiration. &timer1 is the pointer to the name of the specific timer.

if(timer_settime(timer1, NULL, &tempoIniziale, &tempoFinale) == -1)

with this procedure, the timer is armed, so you can make it generate expirations.timer1 is the name of the timer, 0 is the flags. GAPIL book says: <>&tempoIniziale and &tempoFinale are pointers to itimerspec structs. I have not understood well what is the meaning of &old_timer. In GAPIL book you can read:<>

struct sigaction, oldSigAzione

sigaction structs that will be passed as parameter to sigaction POSIX signal handler

sigaction (SIGEV_SIGNAL, NULL, &oldSigAzione)

SIGEV_SIGNAL is the kind of signals it has to handle, NULL Is where it could be placed a pointer to a const struct sigaction, &oldSigAzione is the pointer to the sigaction struct I mentioned before. Here again I have not understood the difference between these two pointers to sigaction struct.

My question is:why the program exits before printing the number 19 of printf("19\n"); and why does not excecutes the printf("Timer scaduto\n"); inside function void termination_handler(int signum) ?

Here my code:

#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;
}

最佳答案

在调用 timer_create() 时,第一个参数应该是一个 clockid,例如 CLOCK_MONOTONIC_POSIX_MONOTONIC_CLOCK 只是一个宏,您可以在编译时使用它来测试系统是否支持 CLOCK_MONOTONIC

sigaction() 的第一个参数应该是信号编号,而不是 SIGEV_SIGNAL。在您的情况下,您使用的是信号 10,但这不是一个好的选择,因为通常这将是预定义的操作系统信号之一。通常您会使用用户定义的信号,如 SIGUSR1 或实时信号,如 SIGRTMIN,因为它们是为应用程序使用而定义的。此外,您对 sigaction() 的调用不会设置信号处理程序,因为第二个参数为 NULL。第二个参数应该是指向新信号操作的指针。相反,您使用的是第三个参数,该参数用于返回先前的信号操作。这允许您临时设置一个新的信号 Action ,同时保存旧的信号 Action ,然后当您完成新 Action 时,您可以将其设置回保存的值。由于您再也不会更改它,因此您不需要获取旧值。同样为了稳健,应该在启动计时器之前设置信号 Action ,因为程序的执行可能会延迟(例如,如果系统真的陷入困境)并且计时器可能会在您到达代码中设置的点之前到期信号处理程序。

正如 R 所提到的,printf() 不是异步信号安全的,因此不应从您的信号处理程序中调用它。

关于c - POSIX 计时器和 POSIX 信号处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9008330/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com