首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >RT计时器奇怪行为

RT计时器奇怪行为
EN

Stack Overflow用户
提问于 2015-10-30 04:47:09
回答 1查看 122关注 0票数 2

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

期望的行为是每5秒产生一个周期性事件,而主执行则休眠30秒,但是我得到了下面的行为。

定时器被创建并初始化,主执行处于休眠状态。5秒后产生计时器事件,分别调用处理程序,当处理程序函数完成主执行时,经过的时间为5秒,但必须是30秒。

代码语言:javascript
复制
/* 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);
}

这是执行输出:

代码语言:javascript
复制
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

有人能帮我弄清楚这里发生了什么吗?

提前谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-10-30 04:55:40

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

The ()函数将挂起调用线程的执行,直到时间过去或将信号传递到线程,其操作是调用信号捕获函数或终止线程或进程。

幸运的是,sleep函数的返回值是睡眠所剩的时间,因此您可以在这样的循环中调用sleep

代码语言:javascript
复制
int t = 30;
while ( t > 0 )
    t = sleep( t );
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33428848

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档