0

我在 ubuntu 上使用 eclipse IDE 来编译我的 c 项目。我有一个计时器。启动定时器后,睡眠或睡眠功能不工作。这是代码;

编辑

/*
 ============================================================================
 Name        : TimerTest.c
 Author      : FK
 Version     :
 Copyright   : Your copyright notice
 Description : Hello World in C, Ansi-style
 ============================================================================
 */

#include <stdio.h>
#include <stdlib.h>         /* , getenv() */
#include <getopt.h>
#include <unistd.h>         /* exec(), daemon() */
#include <stdint.h>
#include <string.h>         /* memset(), strerror() */
#include <errno.h>          /* errno */
#include <libgen.h>         /* basename() */
#include <signal.h>
#include <sys/timex.h>      /* ntp_gettime() */
#include <time.h>

#include "timer/timer.h"

#define CONFIG_TIMER_INTERVAL   100 /* in ms */
/* global vars decalarations */

static uint8_t _terminate = 0;
static int _signo = 0;

static int init_prg(int argc, char *argv[]);
static void timer_callback(void);

/* function implementations */
static void sig_handler(int signo)
{
    /* http://www.yolinux.com/TUTORIALS/C++Signals.html */
    _signo = signo;
    switch (signo)
    {
        case SIGINT: /* Program interrupt. (ctrl-c) */

            _terminate = 1;
            break;
        case SIGTERM:

            _terminate = 1;
            break;
            /* SIGKILL, SIGSTOP yakalanımıyor! */
        default:

            break;
    }

}

int main(int argc, char *argv[])
{
    init_prg(argc, argv);
    /* start super loop */
    while (1)
    {
        printf("test!\n");
        //usleep(1000000);
        sleep(1);

    }
}

static int init_prg(int argc, char *argv[])
{
    int res = -1;

    if (signal(SIGINT, sig_handler) == SIG_ERR)
    {
        //exit(EXIT_FAILURE);
    }

    /* Termination, Generated by "kill" command. */
    if (signal(SIGTERM, sig_handler) == SIG_ERR)
    {
        //exit(EXIT_FAILURE);
    }



    start_timer(2000, &timer_callback);

    if (res != 0)
    {
        //exit(EXIT_FAILURE);
    }

    return res;
}

static void timer_callback(void)
{
    printf("timer works!\n");
}

执行程序后,它会回显“测试!” 迅速。忽略 sleep 或 usleep 命令。如果我注释掉 start_timer 行,它会休眠,在定时器之后它不是。有什么想法吗?

4

2 回答 2

2

您没有显示用于启动计时器的标准化接口。

无论如何,POSIX指定usleep

nanosleep()
setitimer()
timer_create()
timer_delete()
timer_getoverrun()
timer_gettime()
timer_settime()
ualarm()
sleep()

未指定。

nanosleep不应该有这个问题。

nanosleep 的手册页

与 sleep(3) 和 usleep(3) 相比,nanosleep() 具有以下优点:它为指定睡眠间隔提供了更高的分辨率;POSIX.1 明确规定它不与信号交互;它使恢复已被信号处理程序中断的睡眠的任务更容易。

以上建议将您的替换usleep为:

#include <unistd.h>
int my_usleep(useconds_t Usec);

#include <time.h>
int my_usleep(useconds_t Usec)
{
    return nanosleep(&(const struct timespec){ 
      .tv_sec = Usec/100000, .tv_nsec=1000*Usec%1000000}, NULL);
}

应该解决问题。

于 2018-08-14T12:48:15.240 回答
2

您似乎正在使用类似于https://www.teuniz.net/Timer_code/上提供的计时器库。如果您timer.c在该库中打开,您将看到它使用setitimer(ITIMER_REAL, ...). 以这种方式创建的计时器将SIGALRM在计时器到期时生成。反过来,这会将您的程序从sleep()ing 中唤醒。

为什么?因为,如果您阅读 POSIX 规范sleep()(可在http://pubs.opengroup.org/onlinepubs/009695399/ -> Alphabetical index ->获得sleep()),您将阅读。

sleep() 函数将导致调用线程暂停执行,直到参数 seconds 指定的实时秒数已经过去,或者信号被传递到调用线程并且它的动作是调用信号捕获函数或终止进程。

另一方面,如果您没有使用上述库,那么您需要准确显示您的start_timer()函数在做什么。否则,任何试图帮助你的人都是在黑暗中开枪。

解决方案:线程

我认为您唯一的选择是使用单独的线程 - 一个线程用于睡眠任务,另一个用于处理计时器的任务。

于 2018-08-14T14:02:32.543 回答