【发布时间】: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对象在信号处理程序上下文中最后一次写入非信号处理程序上下文时被读取,这也是未定义的行为,反之亦然.你真的不能安全地在信号处理程序中使用非异步安全函数。