C语言 timer_settime在uClinux上调用pthread中的handler函数



我已经得到了以下函数,从pthread_create调用。这个函数做一些工作,设置一个计时器,做一些其他的工作,然后等待计时器过期,然后再进行循环。然而,在计时器的第一次运行,过期后程序退出,我不完全确定为什么。它不应该离开无限while循环。主线程不访问该线程,反之亦然(目前)。

我的猜测是我可能没有正确设置线程,或者计时器没有正确调用处理程序函数。也许从线程中更改IDLE全局变量会导致问题。

我想调用没有信号的处理程序,因此使用SIGEV_THREAD_ID。无论如何,我在主线程中使用SIGUSRx信号。有什么想法吗,我在这里开始了什么可能是错的?

#ifndef sigev_notify_thread_id
#define sigev_notify_thread_id _sigev_un._tid
#endif
volatile sig_atomic_t IDLE = 0;
timer_t timer_id;
struct sigevent sev;
void handler() {
    printf("Timer expired.n");
    IDLE = 0;
}
void *thread_worker() {
    struct itimerspec ts;
    /* setup the handler for timer event */
    memset (&sev, 0, sizeof(struct sigevent));
    sev.sigev_notify = SIGEV_THREAD_ID;
    sev.sigev_value.sival_ptr = NULL;
    sev.sigev_notify_function = handler;
    sev.sigev_notify_attributes = NULL;
    sev.sigev_signo = SIGRTMIN + 1;
    sev.sigev_notify_thread_id = syscall(SYS_gettid);
    /* setup "idle" timer */
    ts.it_value.tv_sec = 55;
    ts.it_value.tv_nsec = 0;
    ts.it_interval.tv_sec = 0;
    ts.it_interval.tv_nsec = 0;
    if (timer_create(0, &sev, &timer_id) == -1) {
        printf("timer_create failed: %d: %sn", errno, strerror(errno));
        exit(3);
    }
    while (1) {
        // do work here before timer gets started that takes 5 seconds
        while (IDLE);   /* wait here until timer_id expires */
        /* setup timer */
        if (timer_settime(timer_id, 0, &ts, NULL) == -1) {
            printf("timer_settime failed: %dn", errno);
            exit(3);
        }
        IDLE = 1;
        // do work here while timer is running but that does not take 10 seconds
    }
}

据我所知,您还没有为SIGUSR1安装信号处理程序,因此通过默认操作,当它被操作时,它会杀死进程。

无论如何,整个事情给我的印象是非常糟糕的设计:

  1. while循环会在等待计时器到期时给你100%的cpu负载。

  2. 这不是你使用SIGEV_THREAD_ID的方式,事实上SIGEV_THREAD_ID并没有真正设置为应用程序可用。相反,libc内部使用它来实现SIGEV_THREAD

  3. 你真的不想使用信号。他们乱。

如果你有线程,为什么不在循环中调用clock_nanosleep呢?当你不能这样做时,计时器主要是有用的,例如,当你不能使用线程时。

最新更新