C中的多个警报?
Posted
技术标签:
【中文标题】C中的多个警报?【英文标题】:Multiple alarms in C? 【发布时间】:2017-05-22 21:04:17 【问题描述】:这可能是一个非常基本的问题,但我正在使用下面的代码来运行一个简单的警报。它可以按我的意愿工作,但我想知道是否有可能同时运行多个警报,每个警报在完成时都会触发不同的功能。有没有办法做到这一点?
#include <signal.h>
#include <sys/time.h>
#include <stdio.h>
#include <time.h>
void alarm_handler(int signum)
printf("five seconds passed!!\n");
int main()
signal(SIGALRM, alarm_handler);
alarm(5);
pause();
return 0;
【问题讨论】:
你试过了吗? 您可以经常使用操作系统特定的功能。在 Linux 上,您会找到timerfd_create
,而在 BSD 上,您可以使用任何打开的文件描述符(即使用 mkstemp
打开的文件描述符)来设置计时器,然后轮询文件描述符……请注意计时器是一种操作系统广泛有限的资源。您可能并不总是可以使用它们。
您可以使用 timer_create (POSIX) 代替警报来轻松实现您的目标。
@PSkocik ,我的经验表明 timer_create
并不像我们希望的那样便携。例如,我在 macOS 上似乎不存在。虽然我可能是错的(我经常是)。
@ConnorOlsen 在 Linux 2.6 及更高版本上,它应该。
【参考方案1】:
没有。根据this source:
警报请求不堆叠;以这种方式只能安排一次 SIGALRM 生成。如果尚未生成 SIGALRM 信号,则调用将导致重新安排生成 SIGALRM 信号的时间。
另一种方法是创建一个priority queue,在其中放置您的任务,然后始终为当前时间与队列顶部任务之间的时间差安排闹钟。
但请务必查看this SO 问题:您在信号处理程序中可以做的事情种类有限。
【讨论】:
【参考方案2】:alarm(2)
不适用,但是,您可以使用 POSIX 计时器来实现您的目标。
您可以将每个计时器设置为在到期时运行不同的信号,或者您可以使用单个信号并通过siginfo_t
将指针传递给计时器,然后您可以根据它决定在处理程序。
例子:
#include <signal.h>
#include <stdio.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
static timer_t tmid0, tmid1;
static void hndlr(int Sig, siginfo_t *Info, void *Ptr)
if(Info->si_value.sival_ptr == &tmid0)
write(2, "tmid0\n", 6);
else
write(2, "tmid1\n", 6);
_exit(0);
int main()
int r = EXIT_SUCCESS;
sigaction(SIGALRM, &(struct sigaction) .sa_sigaction = hndlr, .sa_flags=SA_SIGINFO , 0);
printf("%p %p\n", (void*)&tmid0, (void*)&tmid1);
struct sigevent sev = .sigev_notify = SIGEV_SIGNAL, .sigev_signo = SIGALRM ;
sev.sigev_value.sival_ptr = &tmid0;
if(0>timer_create(CLOCK_REALTIME,&sev,&tmid0))
r=EXIT_FAILURE; goto out;
sev.sigev_value.sival_ptr = &tmid1;
if(0>timer_create(CLOCK_REALTIME,&sev,&tmid1))
r=EXIT_FAILURE; goto out;
if(0>timer_settime(tmid0, 0, &(struct itimerspec const) .it_value=1,0 , NULL) )
r=EXIT_FAILURE; goto out;
//tmid0 expires after 1 second
if(0>timer_settime(tmid1, 0, &(struct itimerspec const) .it_value=3,0 , NULL) )
r=EXIT_FAILURE; goto out;
//tmid1 expires after 3 seconds
for(;;)
pause();
out:
if(r)
perror(0);
return r;
【讨论】:
以上是关于C中的多个警报?的主要内容,如果未能解决你的问题,请参考以下文章
一个视图中的多个警报只能在 swiftui 中始终使用最后一个警报