C 如何在linux中实现2个定时器
我正在尝试将flag变量设置为开启(使用raspbery pi。我需要锁定)500秒(微秒),并连续关闭flag变量300秒(无限长,直到我停止)。我想用两个定时器来实现它 现在在这个程序中,我已经写了5秒和3秒C 如何在linux中实现2个定时器,c,linux,timer,C,Linux,Timer,我正在尝试将flag变量设置为开启(使用raspbery pi。我需要锁定)500秒(微秒),并连续关闭flag变量300秒(无限长,直到我停止)。我想用两个定时器来实现它 现在在这个程序中,我已经写了5秒和3秒 #include <signal.h> #include <stdio.h> #include <string.h> #include <sys/time.h> #include <unistd.h> struct siga
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <unistd.h>
struct sigaction sa;
struct itimerval timer1,timer2;
int count=1;
void timer_handler (int signum)
{
if(count++%2==1)
printf("High\n"); //flag=1
else
printf("Low\n"); //flag=0
}
int main ()
{
/* Install timer_handler as the signal handler for SIGVTALRM. */
memset (&sa, 0, sizeof (sa));
sa.sa_handler = &timer_handler;
sa.sa_flags = SA_RESTART;
sigaction (SIGALRM, &sa, NULL);
int i=0;
while(1){
scanf(" %d",&i);
if(i==1){ // I m starting 2 timers here
timer1.it_value.tv_sec = 0;
timer1.it_value.tv_usec = 1;
timer1.it_interval.tv_sec = 8; //5+3
timer1.it_interval.tv_usec = 0;
timer2.it_value.tv_sec = 5;
timer2.it_value.tv_usec = 0;
timer2.it_interval.tv_sec = 8;
timer2.it_interval.tv_usec = 0;
setitimer (ITIMER_REAL, &timer1, NULL);
setitimer (ITIMER_REAL, &timer2, NULL);
}
else if(i==2) // I m stopping here
{
timer1.it_value.tv_sec = 0;
timer1.it_value.tv_usec = 0;
timer1.it_interval.tv_sec = 0;
timer1.it_interval.tv_usec = 0;
timer2.it_value.tv_sec = 0;
timer2.it_value.tv_usec = 0;
timer2.it_interval.tv_sec = 0;
timer2.it_interval.tv_usec = 0;
setitimer (ITIMER_REAL, &timer1, NULL); // 1st timer on
setitimer (ITIMER_REAL, &timer2, NULL); //2nd timer on
}
}
}
#包括
#包括
#包括
#包括
#包括
struct-sigaction-sa;
结构itimerval timer1,timer2;
整数计数=1;
无效计时器\u处理程序(整数符号)
{
如果(计数+++%2==1)
printf(“高\n”);//标志=1
其他的
printf(“低\n”);//标志=0
}
int main()
{
/*安装计时器\u处理程序作为SIGVTALRM的信号处理程序*/
memset(&sa,0,sizeof(sa));
sa.sa_handler=&timer_handler;
sa.sa_标志=sa_重启;
sigaction(SIGALRM,&sa,NULL);
int i=0;
而(1){
scanf(“%d”、&i);
如果(i==1){//我在这里开始两个计时器
timer1.it_value.tv_sec=0;
timer1.it_value.tv_usec=1;
timer1.it\u interval.tv\u sec=8;//5+3
timer1.it\u interval.tv\u usec=0;
timer2.it_value.tv_sec=5;
timer2.it\u value.tv\u usec=0;
timer2.it_interval.tv_sec=8;
timer2.it\u interval.tv\u usec=0;
setitimer(ITIMER\U REAL和timer1,NULL);
setitimer(ITIMER\U REAL和timer2,NULL);
}
else如果(i==2)//我停在这里
{
timer1.it_value.tv_sec=0;
timer1.it_value.tv_usec=0;
timer1.it_interval.tv_sec=0;
timer1.it\u interval.tv\u usec=0;
timer2.it_value.tv_sec=0;
timer2.it\u value.tv\u usec=0;
timer2.it_interval.tv_sec=0;
timer2.it\u interval.tv\u usec=0;
setitimer(ITIMER_REAL,&timer1,NULL);//第一个计时器打开
setitimer(ITIMER_REAL,&timer2,NULL);//第二个计时器打开
}
}
}
这是我写的代码。
实际发生的是第二个计时器正在运行,而第一个计时器没有运行。我想它被覆盖了
另外,我不想使用睡眠功能,因为它需要更多的时间。我用定时器,因为分辨率是微秒
1.如何使用两个计时器进行此操作2.有没有更好的方法来完成这项任务?只有一个
ITIMER\u REAL
,因此您必须自己创建虚拟计时器。如果你不需要微秒精度,一个简单而可靠的方法是使用一个间隔很小的周期计时器,并在上面实现你的虚拟计时器(因此周期计时器的每一个“滴答声”都会减少你的虚拟计时器)
下面是一个如何实现它的示例:
vtimer.h
vtimer.c
\define\u POSIX\u C\u SOURCE 200101L
#包括“vtimer.h”
#包括
#包括
#包括
#定义NUM_计时器8
静态vtimer*计时器[NUM_timers]={0};
静态void*timoutArgs[NUM_TIMERS]={0};
静态大小计数器=0;
静态挥发性sig_原子滴答=0;
静态无效处理程序(int-signum)
{
(无效)签名;
++蜱虫;
}
静态结构sigaction timerAction={.sa_handler=tickhandler};
静态结构sigaction defaultAction;
静态结构itimerval tickTimerval={0,1000},{0,1000};
静态结构itimerval disableTimerval={0,0},{0,0};
无效vtimer\u开始(vtimer*self,无效*timeoutArg)
{
int=0;
对于(大小idx=0;idx电流=自->毫秒;
}
无效vtimer\u停止(vtimer*self)
{
int=0;
对于(大小idx=0;idx停止计时
setitimer(ITIMER\u REAL和disableTimerval,0);
sigaAction(SIGALRM和defaultAction,0);
}
}
无效vtimer\u调度(无效)
{
while(滴答声)
{
--蜱虫;
对于(大小idx=0;idx当前)
{
定时器[idx]->超时(timoutArgs[idx]);
if(定时器[idx]->周期性)
{
定时器[idx]->电流=定时器[idx]->毫秒;
}
否则vtimer_停止(计时器[idx]);
}
}
}
}
}
使用以下命令的示例程序:
#包括“vtimer.h”
#包括
#包括
静态void timer1\u超时(void*arg)
{
(无效)arg;
放置(“计时器1”);
}
静态void timer2\u超时(void*arg)
{
(无效)arg;
puts(“计时器2”);
}
内部主(空)
{
vtimer timer1=vtimer_init(5000,1,timer1_timeout);
vtimer timer2=vtimer_init(8000,1,timer2_timeout);
vtimer_启动(&timer1,0);
vtimer_启动(&timer2,0);
对于(;;)
{
errno=0;
int c=getchar();
如果(c==EOF&&errno!=EINTR)中断;
如果(c=='q')中断;
vtimer_分派();
}
vtimer_停止(&timer2);
vtimer_停止(&timer1);
返回0;
}
有很多设计决策正在进行中(例如,滴答声的频率应该有多高(这里是1ms),有固定数量的虚拟计时器与动态计时器,使用指针作为“计时器句柄”或整数,等等),所以请考虑您需要什么,并尝试编写自己的。printf不是异步安全的,所以在信号处理器中你可能会有奇怪的行为。哦,好的,谢谢。只是为了调试的目的。如何使用2个计时器?目的无关紧要,这会导致奇怪的行为。信号
#ifndef VTIMER_H
#define VTIMER_H
typedef void (vtimer_timeout)(void *arg);
typedef struct vtimer
{
int msec;
int periodic;
int current;
vtimer_timeout *timeout;
} vtimer;
#define vtimer_init(m, p, cb) { \
.msec=(m), .periodic=(p), .current=0, .timeout=cb}
void vtimer_start(vtimer *self, void *timeoutArg);
void vtimer_stop(vtimer *self);
// call this periodically, e.g. after each interrupted library call:
void vtimer_dispatch();
#endif
#define _POSIX_C_SOURCE 200101L
#include "vtimer.h"
#include <stddef.h>
#include <signal.h>
#include <sys/time.h>
#define NUM_TIMERS 8
static vtimer *timers[NUM_TIMERS] = {0};
static void *timoutArgs[NUM_TIMERS] = {0};
static size_t ntimers = 0;
static volatile sig_atomic_t ticks = 0;
static void tickhandler(int signum)
{
(void)signum;
++ticks;
}
static struct sigaction timerAction = {.sa_handler = tickhandler};
static struct sigaction defaultAction;
static struct itimerval tickTimerval = {{0, 1000}, {0, 1000}};
static struct itimerval disableTimerval = {{0,0},{0,0}};
void vtimer_start(vtimer *self, void *timeoutArg)
{
int found = 0;
for (size_t idx = 0; idx < NUM_TIMERS; ++idx)
{
if (timers[idx] == self)
{
found = 1;
break;
}
}
if (!found)
{
if (ntimers == NUM_TIMERS) return; // or maybe return error
if (!ntimers++)
{
// only start the "ticking" timer when necessary
sigaction(SIGALRM, &timerAction, &defaultAction);
setitimer(ITIMER_REAL, &tickTimerval, 0);
}
for (size_t idx = 0; idx < NUM_TIMERS; ++idx)
{
if (!timers[idx])
{
timers[idx] = self;
timoutArgs[idx] = timeoutArg;
break;
}
}
}
self->current = self->msec;
}
void vtimer_stop(vtimer *self)
{
int found = 0;
for (size_t idx = 0; idx < NUM_TIMERS; ++idx)
{
if (timers[idx] == self)
{
timers[idx] = 0;
found = 1;
break;
}
}
if (found && !--ntimers)
{
// no virtual timers running -> stop ticking timer
setitimer(ITIMER_REAL, &disableTimerval, 0);
sigaction(SIGALRM, &defaultAction, 0);
}
}
void vtimer_dispatch(void)
{
while (ticks)
{
--ticks;
for (size_t idx = 0; idx < NUM_TIMERS; ++idx)
{
if (timers[idx])
{
if (!--(timers[idx]->current))
{
timers[idx]->timeout(timoutArgs[idx]);
if (timers[idx]->periodic)
{
timers[idx]->current = timers[idx]->msec;
}
else vtimer_stop(timers[idx]);
}
}
}
}
}
#include "vtimer.h"
#include <stdio.h>
#include <errno.h>
static void timer1_timeout(void *arg)
{
(void) arg;
puts("timer 1");
}
static void timer2_timeout(void *arg)
{
(void) arg;
puts("timer 2");
}
int main(void)
{
vtimer timer1 = vtimer_init(5000, 1, timer1_timeout);
vtimer timer2 = vtimer_init(8000, 1, timer2_timeout);
vtimer_start(&timer1, 0);
vtimer_start(&timer2, 0);
for (;;)
{
errno = 0;
int c = getchar();
if (c == EOF && errno != EINTR) break;
if (c == 'q') break;
vtimer_dispatch();
}
vtimer_stop(&timer2);
vtimer_stop(&timer1);
return 0;
}