Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何在linux中实现2个定时器_C_Linux_Timer - Fatal编程技术网

C 如何在linux中实现2个定时器

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

我正在尝试将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 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;
}