【问题标题】:C Signal not received from timerC 未收到来自定时器的信号
【发布时间】:2018-05-14 02:07:52
【问题描述】:

我有 2 个定时器来向同一个应用程序提供不同的信号。接收到一个信号,但没有接收到另一个。如果我手动将丢失的信号发送给它,它就会被接收和处理。

还有其他与丢失信号有关的问题,但答案与我的代码一致。这让我认为这是一个计时器问题......但这意味着一个不工作,即使设置方式与一个工作方式相同。这怎么可能?

操作系统为 QNX 6.6 (Posix 1003.1)

对于下面的代码,系统日志输出只包含“Logger received USR2 signal”。

static void setSignalHandler ()
{
    sigset_t setBlk;
    sigemptyset(&setBlk);
    // mask SIGUSR1 and SIGUSR2 on entering signal handler
    sigaddset(&setBlk, SIGUSR1);
    sigaddset(&setBlk, SIGUSR2);
    struct sigaction act;
    act.sa_handler = signalHandler;
    act.sa_mask = setBlk;
    act.sa_flags = 0;

    setSignalAction(SIGHUP, &act); // Hangup
    setSignalAction(SIGINT, &act); // Interrupt
    setSignalAction(SIGQUIT, &act); // Quit
    setSignalAction(SIGABRT, &act); // Abort
    setSignalAction(SIGUSR1, &act); // User signal 1
    setSignalAction(SIGUSR2, &act); // User signal 2
    setSignalAction(SIGTSTP, &act); // Stopped (user)
}

static void setSignalAction (int sig, const struct sigaction * act)
{
    if (sigaction(sig, act, NULL) == -1)
    {
        // error
        perror("Set signal action");
    }
}

static void signalHandler (int sig)
{
    switch (sig)
    {
    case SIGUSR1:
        slogf(_SLOG_SETCODE(_SLOGC_LOGGER, 0), _SLOG_NOTICE, "Logger received USR1 signal");
        ...
        return;

    case SIGUSR2:
        slogf(_SLOG_SETCODE(_SLOGC_LOGGER, 0), _SLOG_NOTICE, "Logger received USR2 signal");
        ...
        return;

    default:
        slogf(_SLOG_SETCODE(_SLOGC_LOGGER, 0), _SLOG_NOTICE, "Logger received signal %d", sig);
        break;
    }
}

这是定时器设置代码。如果我注释掉 SIGUSR2 的那个,仍然看不到 SIGUSR1。

static void setupTimer ()
{
struct sigevent ev;
ev.sigev_notify = SIGEV_SIGNAL;
ev.sigev_signo = SIGUSR2;
ev.sigev_priority = getprio(0);
if (timer_create(CLOCK_MONOTONIC, &ev, &timerTS) == -1)
{
    perror("Failed to setup timer");
    slogf(_SLOG_SETCODE(_SLOGC_LOGGER, 0), _SLOG_ERROR, "Logger failed to setup timestamp timer.");
}

struct sigevent ev2;
ev2.sigev_notify = SIGEV_SIGNAL;
ev2.sigev_signo = SIGUSR1;
ev2.sigev_priority = getprio(0);
if (timer_create(CLOCK_MONOTONIC, &ev2, &timer2) == -1)
{
    perror("Failed to setup timer");
    slogf(_SLOG_SETCODE(_SLOGC_LOGGER, 0), _SLOG_ERROR, "Logger failed to setup timer 2.");
}
}

static void startTimer ()
{
struct itimerspec ts;
ts.it_value.tv_sec = timestampInterval; // this is usually 60
ts.it_value.tv_nsec = 0;
ts.it_interval.tv_sec = timestampInterval;
ts.it_interval.tv_nsec = 0;
if (timer_settime(timerTS, 0, &ts, NULL) == -1)
{
    perror("Failed to start timestamp timer");
    slogf(_SLOG_SETCODE(_SLOGC_LOGGER, 0), _SLOG_ERROR, "Logger failed to start timestamp timer.");
}

ts.it_value.tv_sec = 0;
ts.it_value.tv_nsec = 0;
ts.it_interval.tv_sec = TIMER2_INTERVAL_SEC; // this is 60
ts.it_interval.tv_nsec = 0;
if (timer_settime(timer2, 0, &ts, NULL) == -1)
{
    perror("Failed to start timer2");
    slogf(_SLOG_SETCODE(_SLOGC_LOGGER, 0), _SLOG_ERROR, "Logger failed to start timer2.");
}
}

【问题讨论】:

  • 欢迎来到 Stack Overflow,请查看:stackoverflow.com/help/how-to-ask
  • ts.it_value.tv_sec = ts.it_value.tv_nsec = 0; 导致 timer2 被解除武装。见man timer_settime。要修复,请改用ts.it_value.tv_sec = TIMER2_INTERVAL_SEC;
  • 谢谢。这就是答案。我以为这很简单。

标签: c timer signals qnx


【解决方案1】:

似乎问题出在第二个计时器的 timer_settime 设置上。尝试在 timer2 的 timer_settime 之前将 ts.it_value 设置为非零值?您似乎正在设置要禁用的计时器。

【讨论】:

  • 谢谢。你是对的。现在可以了。我原以为它会立即以 0 设置运行,然后以给定的时间间隔继续运行。我应该更仔细地阅读文档。
猜你喜欢
  • 2021-04-15
  • 1970-01-01
  • 1970-01-01
  • 2013-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多