#include <signal.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
typedef unsigned int uint32;
#define million 1000000L
double duration2ms, duration10ms, duration100ms;
double Task2ms_Raster, Task10ms_Raster, Task100ms_Raster;
timer_t firstTimerID, secondTimerID, thirdTimerID;
void TASK1(Task2ms_Raster)
{
struct timespec start, stop;
double StartTime, StopTime;
int a=1, b=3,c;
if((StartTime = clock_gettime(CLOCK_REALTIME, &start)) == -1)
{
perror("clock gettime");
}
StartTime =start.tv_sec + 0.0000001 * start.tv_nsec;
printf("start time is %lf", StartTime);
printf("value is %d",c);
printf("ETAS1\n");
if((StopTime = clock_gettime(CLOCK_REALTIME, &stop)) == -1)
{
perror("clock gettime");
}
StopTime = stop.tv_sec + 0.0000001 * stop.tv_nsec;
printf("stop time is %lf", StopTime);
duration2ms = StopTime - StartTime;
printf("time difference is= %lf\n", duration2ms);
}
void TASK2(Task10ms_Raster)
{
int a,b,c;
struct timespec start, stop;
double StartTime, StopTime;
if(clock_gettime(CLOCK_REALTIME, &start) == -1) {
perror("clock gettime");
}
StartTime =start.tv_sec + 0.0000001 * start.tv_nsec;
printf("start time is %lf", StartTime);
printf("ETAS2\n");
if((StopTime = clock_gettime(CLOCK_REALTIME, &stop)) == -1)
{
perror("clock gettime");
}
StopTime = stop.tv_sec + 0.0000001 * stop.tv_nsec;
printf("stop time is %lf", StopTime);
duration10ms = (stop.tv_sec - start.tv_sec)
+ (double)(stop.tv_nsec - start.tv_nsec)
/(double)million;
printf("time difference is= %lf\n", duration10ms);
}
void TASK3(Task100ms_Raster)
{
int a,b,c;
struct timespec start, stop;
double StartTime, StopTime;
if(clock_gettime(CLOCK_REALTIME, &start) == -1) {
perror("clock gettime");
}
StartTime =start.tv_sec + 0.0000001 * start.tv_nsec;
printf("start time is %lf", StartTime);
printf("value is %d",c);
printf("ETAS1\n");
if((StopTime = clock_gettime(CLOCK_REALTIME, &stop)) == -1)
{
perror("clock gettime");
}
StopTime = stop.tv_sec + 0.0000001 * stop.tv_nsec;
printf("stop time is %lf", StopTime);
duration100ms = StopTime -StartTime;
printf("time difference is= %lf\n", duration100ms);
}
static void timerHandler(int sig, siginfo_t *si, void *uc)
{
timer_t *tidp;
tidp = si->si_value.sival_ptr;
if (*tidp == firstTimerID)
TASK1(Task2ms_Raster);
else if (*tidp == secondTimerID)
TASK2(Task10ms_Raster);
else if (*tidp == thirdTimerID)
TASK3(Task100ms_Raster);
}
static int makeTimer(char *name, timer_t *timerID, int expireMS, int intervalMS)
{
struct sigevent te;
struct itimerspec its;
struct sigaction sa;
int sigNo = SIGRTMIN;
/* Set up signal handler. */
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = timerHandler;
sigemptyset(&sa.sa_mask);
if (sigaction(sigNo, &sa, NULL) == -1)
{
perror("sigaction");
}
/* Set and enable alarm */
te.sigev_notify = SIGEV_SIGNAL;
te.sigev_signo = sigNo;
te.sigev_value.sival_ptr = timerID;
timer_create(CLOCK_REALTIME, &te, timerID);
its.it_interval.tv_sec = 0;
its.it_interval.tv_nsec = intervalMS * 100000;
its.it_value.tv_sec = 0;
its.it_value.tv_nsec = expireMS * 100000;
timer_settime(*timerID, 0, &its, NULL);
return 1;
}
int main()
{
makeTimer("First Timer", &firstTimerID, 2, 2); //2ms
makeTimer("Second Timer", &secondTimerID, 10, 10); //10ms
makeTimer("Third Timer", &thirdTimerID, 100, 100); //100ms
while(1)
;;
}
我创建了一个计时器,每2ms,10ms和100ms调用一次任务。我正在使用处理程序来处理任务。上面的代码不会中断task10的精确10ms,task3 100ms。它不会在正确的位置中断,输出如下所示。为什么这不是在正确的时间打断?
输出: 10ms的 2ms的 2ms的 10ms的 2ms的 10ms的 2ms的 2ms的 10ms的 2ms的 10ms的 100ms的 2ms的 10ms的 2ms的 10ms的 2ms的 10ms的 2ms的 10ms的 2ms的 10ms的 2ms 10ms的 2ms的 10ms的 100ms的 2ms的 10ms的 2ms的 10ms的 2ms的 10ms的 2ms的 10ms的 2ms的 10ms的 100ms的 2ms的 10ms的 2ms的 2ms的 10ms的 2ms的 2ms的 10ms的 2ms的 2ms的 10ms 2ms 10ms 2ms的 2ms的 10ms的 100ms的 2ms的 2ms的 10ms的 2ms的 10ms的 2ms的 2ms的 10ms的 2ms的 10ms的 2ms的 10ms的 2ms的 10ms的 2ms的 10ms的 100ms的 2ms的 10ms的 2ms的 10ms的 2ms 10ms 2ms 10ms 2ms 是什么原因?
尝试将2,10和100更改为20,100和1000.我怀疑它会奇迹般地工作然后(调用信号处理程序加上'printf'可能需要比2ms更长的时间,并且您正在丢失信号 - - 信号未被排队!)。通常情况下,定时器分辨率应该足够好2ms,(无论如何它都在我的系统上!)。 – Damon
你说的是真的!有时它会工作,有时不会。如何排队信号?有没有其他方法可以调用这个任务? – user3354789
信号不排队(好吧,RT信号做到了一定的限度,但这没有帮助),对此没有什么可做的。除了更快地退出处理程序,没有其他办法。不用调用'printf',你可以原子地增加一个计数器(或者发布一个'eventfd'或一个信号量),然后根据这个值在处理器之外进行实际的打印。或者,如果可能的话,不要频繁地启动计时器。 – Damon