gpt4 book ai didi

c - RT 计时器奇怪的行为

转载 作者:太空宇宙 更新时间:2023-11-03 23:23:23 27 4
gpt4 key购买 nike

我正在学习如何使用 RT 计时器创建周期性事件。我尝试使用这个基于 timer_create 文档示例的示例。

预期的行为是每 5 秒产生一个周期性事件,同时主执行休眠 30 秒,但我得到以下行为。

定时器被创建并在主执行休眠时被初始化。 5 秒后,定时器事件产生,调用相应的处理程序,当处理程序函数完成时,主执行被唤醒,耗时为 5 秒,但必须为 30 秒。

/* gcc main.c -Wall -Wextra -lrt -o timer */ 
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <time.h>

/* Macros *********************************************************************/
#define CLOCKID CLOCK_REALTIME
/* Real-time signals number */
#define RT_SIGNAL_NUM SIGRTMIN

#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE);} while (0)

#define MAIN_SLEEP 30
#define TIMER_TIME 5


/* Global data ****************************************************************/
struct itimerspec gIts;

timer_t gTimerId;

/* Functions ******************************************************************/

static void handler(int sig, siginfo_t *si, void *uc)
{
int or;
timer_t *tidp;
/* Note: calling printf() from a signal handler is not
strictly correct, since printf() is not async-signal-safe;
see signal(7) */

printf("Caught signal %d\n", sig);
signal(sig, SIG_IGN);

}

void main(int argc, char *argv[])
{
struct sigevent sev;
long long freq_nanosecs;
sigset_t mask;
struct sigaction sa;
time_t begin, end;
double time_spent;

(void) argc;
(void) argv;

/* Establish handler for Real-time signal */
printf("Establishing handler for signal %d\n", RT_SIGNAL_NUM);
/* If SA_SIGINFO is specified in sa_flags, then sa_sigaction (instead of
* sa_handler) specifies the signal-handling function for signum.
*/
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = handler;
/* the Signal no would be masked. */
sigemptyset(&sa.sa_mask);
/* Change the action taken by a process on receipt of a specific signal. */
if (-1 == sigaction(RT_SIGNAL_NUM, &sa, NULL))
{
errExit("sigaction");
}

/* Configure timer:
* SIGEV_SIGNAL: Upon timer expiration, generate the signal sigev_signo for
* the process.
*/
sev.sigev_notify = SIGEV_SIGNAL;
sev.sigev_signo = RT_SIGNAL_NUM;
sev.sigev_value.sival_ptr = &gTimerId;
/* Create and init the timer */
if (-1 == timer_create(CLOCKID, &sev, &gTimerId))
{
errExit("timer_create");
}

printf("timer ID is 0x%lx\n", (long) gTimerId);
/* Start the timer */
gIts.it_value.tv_sec = TIMER_TIME ;
gIts.it_value.tv_nsec = 0;
gIts.it_interval.tv_sec = TIMER_TIME;
gIts.it_interval.tv_nsec = 0;
if (-1 == timer_settime(gTimerId, 0, &gIts, NULL))
{
errExit("timer_settime");
}

/* Sleep for a while; meanwhile, the timer may expire multiple times */
struct itimerspec currTime;
printf("Main Sleep for %d seconds\n", MAIN_SLEEP);
begin = time(NULL);
sleep(MAIN_SLEEP);
end = time(NULL);
printf("Main Wake up\n");
time_spent = (double)(end - begin);
timer_gettime(gTimerId, &currTime);
printf("Main sleep elapsed time = %f s %d %d\n",time_spent);
printf("Timer time = %ld s\n",currTime.it_value.tv_sec);

exit(EXIT_SUCCESS);
}

这是执行输出:

Establishing handler for signal 34
timer ID is 0x9522008
Main Sleep for 30 seconds
Caught signal 34
Main Wake up
Main sleep elapsed time = 5.000000 s
Timer time = 4 s

谁能帮我弄清楚这里发生了什么?

提前致谢。

最佳答案

当信号产生时,sleep函数被中断并立即返回。引用 sleep

的手册页

The sleep() function suspends execution of the calling thread until either [the time has] elapsed or a signal is delivered to the thread and its action is to invoke a signal-catching function or to terminate the thread or process.

幸运的是,sleep 函数的返回值是剩余 sleep 时间,因此您可以像这样简单地在循环中调用 sleep

int t = 30;
while ( t > 0 )
t = sleep( t );

关于c - RT 计时器奇怪的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33428848/

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