Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/hadoop/6.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 POSIX定时器-具有多个定时器_C_Linux_Posix - Fatal编程技术网

C POSIX定时器-具有多个定时器

C POSIX定时器-具有多个定时器,c,linux,posix,C,Linux,Posix,我试图在我的系统中有两个计时器,用于两个不同的目的,但我不明白为什么它不起作用。有人能帮我吗?另外,处理程序代码应该是一个简单的最小值,这样任务本身就不会干扰滴答声了吗?我还可以定义单独的处理程序吗 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <signal.h> #include <netinet/

我试图在我的系统中有两个计时器,用于两个不同的目的,但我不明白为什么它不起作用。有人能帮我吗?另外,处理程序代码应该是一个简单的最小值,这样任务本身就不会干扰滴答声了吗?我还可以定义单独的处理程序吗

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <netinet/in.h>
#include <linux/socket.h>
#include <time.h>


#define SIGTIMER (SIGRTMAX)
#define SIG SIGUSR1
static timer_t     tid;
static timer_t     tid2;

void SignalHandler(int, siginfo_t*, void* );
timer_t SetTimer(int, int, int);

int main(int argc, char *argv[]) {


    struct sigaction sigact;
    sigemptyset(&sigact.sa_mask);
    sigact.sa_flags = SA_SIGINFO;
    sigact.sa_sigaction = SignalHandler;
    // set up sigaction to catch signal
    if (sigaction(SIGTIMER, &sigact, NULL) == -1) {
        perror("sigaction failed");
        exit( EXIT_FAILURE );
    }

    // Establish a handler to catch CTRL+c and use it for exiting.
    sigaction(SIGINT, &sigact, NULL);
    tid=SetTimer(SIGTIMER, 1000, 1);

    struct sigaction sa;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = SA_SIGINFO;
    sa.sa_sigaction = SignalHandler;
    // set up sigaction to catch signal
    if (sigaction(SIG, &sa, NULL) == -1) {
        perror("sa failed");
        exit( EXIT_FAILURE );
    }

    // Establish a handler to catch CTRL+c and use it for exiting.
    sigaction(SIGINT, &sa, NULL);
    tid2=SetTimer(SIG, 1000, 3);
    for(;;);
    return 0;
}

void SignalHandler(int signo, siginfo_t* info, void* context)
{
    if (signo == SIGTIMER) {
        printf("Command Caller has ticked\n");

    }else if (signo == SIG) {
        printf("Data Caller has ticked\n");

    } else if (signo == SIGINT) {
        timer_delete(tid);
        perror("Crtl+c cached!");
        exit(1);  // exit if CRTL/C is issued
    }
}
timer_t SetTimer(int signo, int sec, int mode)
{
    static struct sigevent sigev;
    static timer_t tid;
    static struct itimerspec itval;
    static struct itimerspec oitval;

    // Create the POSIX timer to generate signo
    sigev.sigev_notify = SIGEV_SIGNAL;
    sigev.sigev_signo = signo;
    sigev.sigev_value.sival_ptr = &tid;

    if (timer_create(CLOCK_REALTIME, &sigev, &tid) == 0) {
        itval.it_value.tv_sec = sec / 1000;
        itval.it_value.tv_nsec = (long)(sec % 1000) * (1000000L);

        if (mode == 1) {
            itval.it_interval.tv_sec = itval.it_value.tv_sec;
            itval.it_interval.tv_nsec = itval.it_value.tv_nsec;
        }
        else {
            itval.it_interval.tv_sec = 0;
            itval.it_interval.tv_nsec = 0;
        }

        if (timer_settime(tid, 0, &itval, &oitval) != 0) {
            perror("time_settime error!");
        }
    }
    else {
        perror("timer_create error!");
        return NULL;
    }
    return tid;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义SIGTIMER(SIGRTMAX)
#定义SIG SIGUSR1
静态定时器tid;
静态定时器tid2;
void信号处理器(int,siginfo_t*,void*);
定时器设置定时器(int,int,int);
int main(int argc,char*argv[]){
struct-sigaction-sigact;
sigemptyset(&sigact.sa_mask);
sigact.sa_flags=sa_SIGINFO;
sigact.sa_sigaction=SignalHandler;
//设置sigaction以捕捉信号
if(sigaction(SIGTIMER,&sigact,NULL)=-1){
perror(“sigaction失败”);
退出(退出失败);
}
//建立一个处理程序来捕获CTRL+c并使用它退出。
sigaction(SIGINT,&sigact,NULL);
tid=设置计时器(SIGTIMER,1000,1);
struct-sigaction-sa;
sigemptyset(和sa.sa_面具);
sa.sa_flags=sa_SIGINFO;
sa.sa_sigaction=信号处理器;
//设置sigaction以捕捉信号
if(sigaction(SIG,&sa,NULL)=-1){
perror(“sa失败”);
退出(退出失败);
}
//建立一个处理程序来捕获CTRL+c并使用它退出。
sigation(SIGINT,&sa,NULL);
tid2=设置定时器(信号强度,1000,3);
对于(;);
返回0;
}
void SignalHandler(int signo、siginfo\u t*info、void*context)
{
if(signo==SIGTIMER){
printf(“命令调用方已勾选\n”);
}else if(signo==SIG){
printf(“数据调用方已勾选\n”);
}else if(signo==SIGINT){
定时删除(tid);
perror(“Crtl+c缓存!”);
退出(1);//如果发出CRTL/C,则退出
}
}
定时器设置定时器(整数符号、整数秒、整数模式)
{
静态结构sigev;
静态定时器tid;
静态结构itimerspec itval;
静态结构itimerspec oitval;
//创建POSIX计时器以生成signo
sigev.sigev_notify=sigev_信号;
sigev.sigev_signo=signo;
sigev.sigev_value.sival_ptr=&tid;
如果(计时器\u创建(时钟\u实时,&sigev,&tid)==0){
itval.it_value.tv_sec=sec/1000;
itval.it_value.tv_nsec=(长)(秒%1000)*(1000000L);
如果(模式==1){
itval.it_interval.tv_sec=itval.it_value.tv_sec;
itval.it_interval.tv_nsec=itval.it_value.tv_nsec;
}
否则{
itval.it_interval.tv_sec=0;
itval.it_interval.tv_nsec=0;
}
如果(计时器设置时间(tid、0、itval和oitval)!=0){
perror(“时间设置错误!”);
}
}
否则{
perror(“计时器创建错误!”);
返回NULL;
}
返回tid;
}

当您使用此
tid2=SetTimer(SIG,1000,3)定义第二个计时器时,您的代码将此计时器配置为一次性计时器

    if (mode == 1) {
        itval.it_interval.tv_sec = itval.it_value.tv_sec;       // here you arm the timer periodically (that's the meaning of it_interval
        itval.it_interval.tv_nsec = itval.it_value.tv_nsec;
    }
    else {
        itval.it_interval.tv_sec = 0;     // here you arm the timer once
        itval.it_interval.tv_nsec = 0;
    }
如果您将第二个计时器配置为模式=1,如
tid2=SetTimer(SIG,1000,4),您将在控制台上获得:

Command Caller has ticked
Data Caller has ticked
Command Caller has ticked
Data Caller has ticked
Command Caller has ticked
Data Caller has ticked
^CCrtl+c cached!: Success

您可以为计时器使用不同的处理程序,因为您使用不同的信号来捕获它们的过期。

我在计时器部分发现了一个错误。我发现代码随机冻结。有什么想法吗?我根据数据调用方信号调用一个函数。@user489152:就您的新问题提出一个新问题,并提供有关被调用函数的详细信息,可能问题隐藏在其中。我这里有一些竞争条件。可能是因为printf的声明吗??