Однако не с 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;
}
person
PSkocik
schedule
23.05.2017
timerfd_create
, а в BSD вы можете использовать любой открытый файловый дескриптор (т. е. тот, который открыт с помощьюmkstemp
), чтобы установить таймер, а затем опросить файловые дескрипторы... Имейте в виду, что таймеры являются ограниченным ресурсом ОС. Вы не всегда можете иметь их в наличии. - person Myst   schedule 23.05.2017timer_create
не так портативна, как хотелось бы. Например, меня не существует в macOS. Хотя могу ошибаться (часто ошибаюсь). - person Myst   schedule 23.05.2017