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中的多个警报?的主要内容,如果未能解决你的问题,请参考以下文章

android中的多个警报

一个视图中的多个警报只能在 swiftui 中始终使用最后一个警报

检查表单中的多个 div,如果 div 没有指定的类,请发出警报并阻止提交

php中的音频警报

Javascript 和 HTML 中的数字警报

如何直接为警报注册通知,而不仅仅是横幅? XCode 中的 Swift 或 Objective C