定时器和信号问题

发布于 2024-11-02 08:50:42 字数 172 浏览 0 评论 0原文

我已经使用timer_create() API 实现了一个POSIX 计时器,当计时器到期时(我已经为其放置了处理程序代码),这将生成SIGUSR1。现在的问题是,如果这个程序收到另一个 SIGUSR1,那么相同的信号处理程序将被调用并捕获。

有什么方法可以防止这种情况,以便处理程序可以捕获仅由计时器生成的信号?

I have implemented a POSIX timer using timer_create( ) API, and this will generate SIGUSR1 when the timer expires for which i have put a handler code. Now the problem is, if this program receives another SIGUSR1, then the same signal handler will be invoked and caught.

Is there any way to prevent this, so that the handler can catch signals only generated by the timer?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

默嘫て 2024-11-09 08:50:42

这对你有用吗? (修改了timer_create手册页中示例的代码。)

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <time.h>

#define CLOCKID CLOCK_REALTIME
#define SIG SIGUSR1
timer_t timerid;


static void handler(int sig, siginfo_t *si, void *uc)
{
    if(si->si_value.sival_ptr != &timerid){
        printf("Stray signal\n");
    } else {
        printf("Caught signal %d from timer\n", sig);
    }
}

int main(int argc, char *argv[])
{
    struct sigevent sev;
    struct itimerspec its;
    long long freq_nanosecs;
    sigset_t mask;
    struct sigaction sa;

    printf("Establishing handler for signal %d\n", SIG);
    sa.sa_flags = SA_SIGINFO;
    sa.sa_sigaction = handler;
    sigemptyset(&sa.sa_mask);
    sigaction(SIG, &sa, NULL);

    sev.sigev_notify = SIGEV_SIGNAL;
    sev.sigev_signo = SIG;
    sev.sigev_value.sival_ptr = &timerid;
    timer_create(CLOCKID, &sev, &timerid);
    /* Start the timer */

    its.it_value.tv_sec = 10;
    its.it_value.tv_nsec = 0;
    its.it_interval.tv_sec = its.it_value.tv_sec;
    its.it_interval.tv_nsec = its.it_value.tv_nsec;

    timer_settime(timerid, 0, &its, NULL);
    sleep(100);
    exit(EXIT_SUCCESS);
}

当捕获来自定时器的信号时,将显示Caught signal 10 from timer。否则会显示杂散信号

Will this work for you? (Modified the code from example in timer_create man page.)

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <time.h>

#define CLOCKID CLOCK_REALTIME
#define SIG SIGUSR1
timer_t timerid;


static void handler(int sig, siginfo_t *si, void *uc)
{
    if(si->si_value.sival_ptr != &timerid){
        printf("Stray signal\n");
    } else {
        printf("Caught signal %d from timer\n", sig);
    }
}

int main(int argc, char *argv[])
{
    struct sigevent sev;
    struct itimerspec its;
    long long freq_nanosecs;
    sigset_t mask;
    struct sigaction sa;

    printf("Establishing handler for signal %d\n", SIG);
    sa.sa_flags = SA_SIGINFO;
    sa.sa_sigaction = handler;
    sigemptyset(&sa.sa_mask);
    sigaction(SIG, &sa, NULL);

    sev.sigev_notify = SIGEV_SIGNAL;
    sev.sigev_signo = SIG;
    sev.sigev_value.sival_ptr = &timerid;
    timer_create(CLOCKID, &sev, &timerid);
    /* Start the timer */

    its.it_value.tv_sec = 10;
    its.it_value.tv_nsec = 0;
    its.it_interval.tv_sec = its.it_value.tv_sec;
    its.it_interval.tv_nsec = its.it_value.tv_nsec;

    timer_settime(timerid, 0, &its, NULL);
    sleep(100);
    exit(EXIT_SUCCESS);
}

When signal from timer is caught Caught signal 10 from timer will be displayed. Otherwise Stray signal will be displayed.

2024-11-09 08:50:42

问题是你是否真的需要使用信号。您可能会考虑使用计时器到期时将调用的回调:

void cbf(union sigval);
struct sigevent sev;
timer_t timer;

sev.sigev_notify = SIGEV_THREAD;
sev.sigev_notify_function = cbf; //this function will be called when timer expires
sev.sigev_value.sival_ptr = (void*) arg;//this argument will be passed to cbf
timer_create(CLOCK_MONOTONIC, &sev, &timer);

回调函数将在新线程中调用。

The question is whether you really need to use signals. You may think of using callback that will be called when the timer expires:

void cbf(union sigval);
struct sigevent sev;
timer_t timer;

sev.sigev_notify = SIGEV_THREAD;
sev.sigev_notify_function = cbf; //this function will be called when timer expires
sev.sigev_value.sival_ptr = (void*) arg;//this argument will be passed to cbf
timer_create(CLOCK_MONOTONIC, &sev, &timer);

The callback function will be called in a new thread.

顾忌 2024-11-09 08:50:42

不,没有简单的方法。如果您有其他东西与计时器一起生成 SIGUSR1,为什么不使用 SIGUSR2 代替计时器呢?如果这还不够,请为您的应用程序使用实时信号之一。

如果它必须能够处理来自计时器和其他源的相同信号,那么根据速度、数量、系统等,您可以尝试在注册计时器之前设置一个时间戳,了解计时器大约退出的时间,然后在信号处理程序中尝试推断它是否在时间裕度内。我强烈建议不要使用这种方法,而是重新设计你正在做的事情。

No, there is no easy way. Why don't you use SIGUSR2 instead for your timers if you have something else generating SIGUSR1 together with your timer. If that is not enough, use one of the real time signals for your application.

If it must be able to handle the same signal from the timer and some other source, then depending on how fast, how many, what system, etc etc you could try setting a timestamp before registering a timer on when the timer will approximately exit, and then in the signal handler try to deduce if it was within time margin. I would strongly advise not to use this approach, but instead redesign what you are doing.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文