【问题标题】:Linux C timer - signal disrupts current processLinux C 定时器 - 信号中断当前进程
【发布时间】:2020-04-10 22:06:40
【问题描述】:

我正在开发一个具有特定时间限制的应用程序,这样事件应该每 200us 发生一次(理想情况下是准确的)。我正在尝试使用计时器和信号来做到这一点。

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

timer_t timer_id;

void start_timer(void)
{
    struct itimerspec value;

    value.it_value.tv_sec = 0;
    value.it_value.tv_nsec = 20000;

    value.it_interval.tv_sec = 0;
    value.it_interval.tv_nsec = 200000;

    timer_create(CLOCK_REALTIME, NULL, &timer_id);
    timer_settime(timer_id, 0, &value, NULL);
}

void handler(int sig) {
     printf("in handler\n");
}

void *my_thread(void *ignore)
{
    (void)ignore;

    start_timer();
    // Sleep forever
    while(1) sleep(1000);
}

int main()
{
    pthread_t thread_id;

    (void) signal(SIGALRM, handler);
    pthread_create(&thread_id, NULL, my_thread, NULL);
    // sleep is a placeholder for this SO question.  I want to do 
    // other processing here
    sleep(5000);
    printf("sleep finished\n");
}

200us 后调用信号处理程序。它似乎在 sleep(5000) 行运行时被调用,因为“睡眠完成”消息显示较早。我希望计时器中断启动计时器的线程,而不是主进程。这就是为什么我创建了一个线程来启动它。有没有办法让信号只中止线程上的当前指令而不是主进程?我知道当处理程序运行时其他线程/进程将被阻止,但我希望它们之后继续,好像什么也没发生一样。例如,在这种情况下,我想至少睡 5000 秒。

【问题讨论】:

  • 先打印哪一行?
  • 在信号处理程序中调用非异步安全函数的未定义行为。
  • @TonyTannous "in handler" 优先显示。
  • @EOF:除非信号处理程序中断了非 AS 安全函数,否则它实际上不是 UB,这不应该是这种情况(如果 OP 正确屏蔽了信号,也不会如此)。跨度>
  • @R..GitHubSTOPHELPINGICE 如果任何非无锁原子或volatile sig_atomic_t 对象在信号处理程序上下文中最后一次写入非信号处理程序上下文时被读取,这也是未定义的行为,反之亦然.你真的不能安全地在信号处理程序中使用非异步安全函数。

标签: c signals


【解决方案1】:

是的,您可以在启动任何其他线程之前在主线程中阻塞信号 (pthread_sigmask),并且只能在打算处理它的线程中解除阻塞。这将确保它到达您想要的线程中。

但是,如果您已经有线程,您确定确实需要一个计时器来为此生成信号吗? clock_nanosleep 应该允许在精确的时间唤醒睡眠,并避免所有可怕的信号。

【讨论】:

  • 谢谢,clock_nanosleep 正是我要找的。我以前使用 nanosleep,但一直遇到时钟漂移问题。
猜你喜欢
  • 2016-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-05
  • 2016-07-13
  • 2011-09-06
  • 1970-01-01
相关资源
最近更新 更多