精确定时调度模块开发设计

来源:互联网 发布:数据统计 编辑:程序博客网 时间:2024/06/16 02:34

精确定时调度模块主要是负责某些函数定时的执行,主要思路是:

1.设计包含函数指针的结构体和相同类型的结构体数组;

2.使用Linux自带的Posix定时器以及sigaction函数、Linux信号机制、信号量控制线程同步实现对执行的触发;

3.将某个需要执行的函数注册到结构体中,再将该结构体放到结构体数组中空的位置;

4.在等到信号量之后,就会执行掉结构体中所有被注册的函数,也就是说如果是秒级轮询任务,注册的函数包括100个,那么时间到触发信号量增加之后,注册的100个函数将被顺    序执行,因此需要100个函数总的执行时间之和不超过1s;

=======================================================================

定时器部分的实现:

使用 sigaction 函数:
 signal 函数的使用方法简单,但并不属于 POSIX 标准,在各类 UNIX 平台上的实现不尽相同,因此其用途受

到了一定的限制。而 POSIX 标准定义的信号处理接口是 sigaction 函数,其接口头文件及原型如下:
 #include <signal.h>
 int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);

 ◆ signum:要操作的信号。
 ◆ act:要设置的对信号的新处理方式。
 ◆ oldact:原来对信号的处理方式。
 ◆ 返回值:0 表示成功,-1 表示有错误发生。

 struct sigaction 类型用来描述对信号的处理,定义如下:
 struct sigaction
 {
  void     (*sa_handler)(int);
  void     (*sa_sigaction)(int, siginfo_t *, void *);
  sigset_t  sa_mask;
  int       sa_flags;
  void     (*sa_restorer)(void);
 };

 在这个结构体中,成员 sa_handler 是一个函数指针,其含义与 signal 函数中的信号处理函数类似。成员

sa_sigaction 则是另一个信号处理函数,它有三个参数,可以获得关于信号的更详细的信息。当 sa_flags 成员的值

包含了 SA_SIGINFO 标志时,系统将使用 sa_sigaction 函数作为信号处理函数,否则使用 sa_handler 作为信号处理

函数。在某些系统中,成员 sa_handler 与 sa_sigaction 被放在联合体中,因此使用时不要同时设置。
 sa_mask 成员用来指定在信号处理函数执行期间需要被屏蔽的信号,特别是当某个信号被处理时,它自身会被

自动放入进程的信号掩码,因此在信号处理函数执行期间这个信号不会再度发生。
 sa_flags 成员用于指定信号处理的行为,它可以是一下值的“按位或”组合。
 
 ◆ SA_RESTART:使被信号打断的系统调用自动重新发起。
 ◆ SA_NOCLDSTOP:使父进程在它的子进程暂停或继续运行时不会收到 SIGCHLD 信号。
 ◆ SA_NOCLDWAIT:使父进程在它的子进程退出时不会收到 SIGCHLD 信号,这时子进程如果退出也不会成为僵

尸进程。
 ◆ SA_NODEFER:使对信号的屏蔽无效,即在信号处理函数执行期间仍能发出这个信号。
 ◆ SA_RESETHAND:信号处理之后重新设置为默认的处理方式。
 ◆ SA_SIGINFO:使用 sa_sigaction 成员而不是 sa_handler 作为信号处理函数。

===================================================

代码实现: 

int PosixTimer(){    timer_t timer1, timer2,timer3,timer4;    struct sigevent evp1, evp2, evp3, evp4;    struct sigaction act1, act2, act3, act4;    struct itimerspec it1,it2,it3,it4;        memset( &act1, 0, sizeof(act1) );    act1.sa_handler = sig_handler;    act1.sa_flags = 0;    sigemptyset( &act1.sa_mask );    if( sigaction( SIGRTMIN+1, &act1, NULL ) == -1 )     {        TME_TRCMSG(1,"fail to sigaction");        exit(-1);    }        /* Timer1 Init */    memset( &evp1, 0, sizeof(struct sigevent) );    evp1.sigev_signo = SIGRTMIN+1;    evp1.sigev_notify = SIGEV_SIGNAL;    if( timer_create(CLOCK_MONOTONIC, &evp1, &timer1) == -1 )    {        TME_TRCMSG(1,"fail to timer_create");        exit(-1);    }    it1.it_interval.tv_sec = 0;    it1.it_interval.tv_nsec = 1000000;    it1.it_value.tv_sec = 0;    it1.it_value.tv_nsec = 1;        if( timer_settime(timer1, 0, &it1, 0) == -1 )    {        TME_TRCMSG(1,"fail to timer_settime");        exit(-1);    }       return 0;}




0 0
原创粉丝点击