问题是我正在尝试运行可以同时触发不同计时器的代码。也就是说,当用户键入3时,触发第一个。如果在到期之前引入另一个3,则将启动第二个计时器,并且将显示两个触发器之间的差异。在这种情况下,timer_gettime只能运行一次。我尝试了所有我能想象的东西,但是,it_value_tv_sec和_nsec在第一次到期后返回零。
以下是我正在测试的代码:
提前谢谢!
#include <stdio.h>
#include <signal.h>
#include <time.h>
timer_t firstTimerID;
timer_t secondTimerID;
timer_t thirdTimerID;
timer_t fourthTimerID;
int z=0;
int a=0;
int t_block3=4;
float delay_blocks;
struct itimerspec it;
struct itimerspec its;
static void timerHandler( int sig, siginfo_t *si, void *uc )
{
timer_t *tidp;
tidp = si->si_value.sival_ptr;
if ( *tidp == firstTimerID ){
printf("First timer\n");
}
else if ( *tidp == secondTimerID ){
printf("Second timer\n");
}
else if ( *tidp == thirdTimerID ){
printf("Third timer\n");
}
else if ( *tidp == fourthTimerID ){
printf("Fourth timer\n");
}
z--;
printf("%d", z);
}
static int makeTimer( timer_t *timerID, int time)
{
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; //Action when singal is triggered
sigemptyset(&sa.sa_mask);
if (sigaction(sigNo, &sa, NULL) == -1) {
perror("sigaction");
}
// Set and enable alarm
te.sigev_notify = SIGEV_SIGNAL; //Gnerate alarm upon expiration
te.sigev_signo = sigNo; //SIGALRM
te.sigev_value.sival_ptr = timerID; //Timer ID
//Create a per_process timer using the timer ID
timer_create(CLOCK_REALTIME, &te, timerID);
//Interval for starting again
its.it_interval.tv_sec = 0 ;
its.it_interval.tv_nsec = 0;
//Timer time
its.it_value.tv_sec = time;
its.it_value.tv_nsec = 0;
//Arm/disarmer a per process time
timer_settime(*timerID, 0, &its, NULL);
return 1;
}
int main(){
while (1){
printf("Enter the number of the block\n");
if (scanf(" %d", &a) == 1){
switch(a){
case 3: printf("Block number three, belt will proceed to stop in 12 seconds\n");
if (z==0){
makeTimer(&firstTimerID, t_block3);
}else if (z==1){
makeTimer(&secondTimerID, 4);
timer_gettime(&firstTimerID,&it);
delay_blocks=t_block3-(it.it_value.tv_sec+(it.it_value.tv_nsec*0.000000001));
printf("Difference between the first and the second timer = %f\n", delay_blocks);
}else if (z==2){
makeTimer(&thirdTimerID, 4);
}else if (z==3){
makeTimer(&fourthTimerID, 4);
}
z++;
break;
case 2: printf("Block number two, belt will proceed to stop in 10 seconds\n");
//sleep(1);
break;
case 4: printf("Block number four, belt won't stop\n");
//sleep(1);
break;
default:printf("Wrong lecture\n");
}
}
}
}
一旦收到第一个信号,我也尝试使用timer_delete,但在这种情况下,总是调用gettime,它会返回相同的值,无论是同一时间还是第三个。
答案 0 :(得分:0)
看起来您的问题是您每次都在重新创建计时器。 仅调用timer_create一次并重用相同的计时器 我在下面有一个工作示例。
#include <stdio.h>
#include <signal.h>
#include <time.h>
timer_t firstTimerID;
timer_t secondTimerID;
timer_t thirdTimerID;
timer_t fourthTimerID;
int z = 0;
int a = 0;
int t_block3 = 4;
float delay_blocks;
static void timerHandler (int sig, siginfo_t * si, void *uc) {
timer_t *tidp;
tidp = si->si_value.sival_ptr;
if (*tidp == firstTimerID) {
printf ("First timer\n");
} else if (*tidp == secondTimerID) {
printf ("Second timer\n");
} else if (*tidp == thirdTimerID) {
printf ("Third timer\n");
} else if (*tidp == fourthTimerID) {
printf ("Fourth timer\n");
}
z--;
printf ("%d\n", z);
}
static int makeTimer (timer_t * timerID) {
struct sigevent te;
struct sigaction sa;
int sigNo = SIGRTMIN;
// Set up signal handler.
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = timerHandler; //Action when singal is triggered
sigemptyset (&sa.sa_mask);
if (sigaction (sigNo, &sa, NULL) == -1) {
perror ("sigaction");
}
// Set and enable alarm
te.sigev_notify = SIGEV_SIGNAL; //Gnerate alarm upon expiration
te.sigev_signo = sigNo; //SIGALRM
te.sigev_value.sival_ptr = timerID; //Timer ID
//Create a per_process timer using the timer ID
timer_create (CLOCK_REALTIME, &te, timerID);
}
static int setTimer(timer_t * timerID, int time) {
struct itimerspec its;
//Interval for starting again
its.it_interval.tv_sec = 0;
its.it_interval.tv_nsec = 0;
//Timer time
its.it_value.tv_sec = time;
its.it_value.tv_nsec = 0;
//Arm/disarmer a per process time
timer_settime (*timerID, 0, &its, NULL);
return 1;
}
int main () {
struct itimerspec it;
makeTimer(&firstTimerID);
makeTimer(&secondTimerID);
makeTimer(&thirdTimerID);
makeTimer(&fourthTimerID);
while (1) {
printf ("Enter the number of the block\n");
if (scanf (" %d", &a) == 1) {
switch (a) {
case 3:
printf
("Block number three, belt will proceed to stop in 12 seconds\n");
if (z == 0) {
setTimer (&firstTimerID, t_block3);
} else if (z == 1) {
setTimer (&secondTimerID, 4);
timer_gettime (&firstTimerID, &it);
delay_blocks =
t_block3 - (it.it_value.tv_sec +
(it.it_value.tv_nsec * 0.000000001));
printf ("Difference between the first and the second timer = %f\n",
delay_blocks);
} else if (z == 2) {
setTimer (&thirdTimerID, 4);
} else if (z == 3) {
setTimer (&fourthTimerID, 4);
}
z++;
break;
case 2:
printf
("Block number two, belt will proceed to stop in 10 seconds\n");
//sleep(1);
break;
case 4:
printf ("Block number four, belt won't stop\n");
//sleep(1);
break;
default:
printf ("Wrong lecture\n");
}
}
}
}
答案 1 :(得分:0)
当你将it_interval.tv_sec + it_interval.tv_nec设置为零时,你就有了一次性计时器。
如此处所述http://man7.org/linux/man-pages/man2/timer_settime.2.html
问候