#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <time.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
timer_t timer = {0};
struct sigevent sev = {0};
struct sigaction sa = {0};
struct itimerspec its = {0};
static void timer_handler(int sig, siginfo_t *si, void *pri)
{
printf("timer_handler running, sival_ptr = %p, timer = %p\n", si->_sifields._rt.si_sigval.sival_ptr, &timer);
return;
}
int main(int argc, char *argv[])
{
/*
SIGEV_NONE : 定时器超时后不使用异步通知,可能的情况是使用timer_gettime来监控定时器;
SIGEV_SIGNAL : 一旦超时,产生一个信号,任何时候,至多只有一个信号会发送到队列里面,可以使用timer_getoverrun来获取超时次数;
SIGEV_THREAD : 新建一个线程去处理,该线程执行sigev_notif_function为入口函数;
SIGEV_THREAD_ID : linux独有,发出一个信号,和SIG_NAL类似,只不过该信号发送到指定的线程,如果 sigev_notify 设置该值时,需要同时指定 _sigev_un._tid 的值,例如使用 gettid();
*/
sev.sigev_notify = SIGEV_SIGNAL;
sev.sigev_signo = SIGRTMIN;
sev.sigev_value.sival_ptr = &timer;
/*
sa_handler和sa_sigaction,代表新的信号处理函数,其他意义请参考signal()。
sa_mask 用来设置在处理该信号时暂时将sa_mask 指定的信号搁置。
sa_restorer 此参数没有使用。
sa_flags 用来设置信号处理的其他相关操作,下列的数值可用。
OR 运算(|)组合
A_NOCLDSTOP : 如果参数signum为SIGCHLD,则当子进程暂停时并不会通知父进程
SA_ONESHOT/SA_RESETHAND:当调用新的信号处理函数前,将此信号处理方式改为系统预设的方式。
SA_RESTART:被信号中断的系统调用会自行重启
SA_NOMASK/SA_NODEFER:在处理此信号未结束前不理会此信号的再次到来。
SA_SIGINFO:表示信号附带的siginfo_t可以传送到信号处理函数。应在使用sa_sigaction()函数的时候设置此标志位。
*/
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = timer_handler;
its.it_interval.tv_sec = 1;
its.it_interval.tv_nsec = 0;
its.it_value.tv_sec = 1;
its.it_value.tv_nsec = 0;
if(sigemptyset(&sa.sa_mask) == -1)
{
perror("sigemptyset error\n");
}
if(sigaction(SIGRTMIN, &sa, NULL) == -1)
{
perror("sigaciton error\n");
}
if(timer_create(CLOCK_REALTIME, &sev, &timer) != 0)
{
perror("timer_create error\n");
}
if(timer_settime(timer, 0, &its, NULL) != 0)
{
perror("timer_create error\n");
}
while(1)
{
pause();
}
}
linux posix定时器
于 2023-12-07 20:05:11 首次发布