在使用MONOTONIC_CLOCK的情况下,很难找到MONOTONIC CLOCK定时器。
还有,想使用 setitimer() 系统 API
的人,在大多数系统中都使用 REALTIME_CLOCK
。
所以,我调查了 timer_create()
api 和 timer_settime()
api,它是我想要使用的定时器时钟的更底层控制。
下面是系统信号和定时器的使用示例。
在堆栈溢出中,我没有自己的代码存储库空间。 所以,我正在编写示例代码以进行 self 回答。
最佳答案
它正在使用系统MONOTONIC_CLOCK 计时器。
这是一些使用 linux monotonic timer 调用的例子,它是带有系统保留信号的回调。
我希望有能力的人添加另一个通知线程消息或SIGEV_THREAD代码示例。
examples:: alarmtest.c
在大多数 linux 系统上编译。
gcc -o alarmtest alarmtest.c -lrt
-- 示例源代码 --
/*********************************************************************
Copyright [2015] [KT Ahn, cpplover@daum.net, kts.ahn@gmail.com]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
**********************************************************************/
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <time.h>
void timer_handler (int signum)
{
static int count = 0;
unsigned int clktime;
struct timespec res;
clock_gettime(CLOCK_MONOTONIC, &res);
clktime = res.tv_sec*1000+res.tv_nsec/1000000;
printf("%08d:%s]timer expired %d timers\n",clktime,__FUNCTION__, ++count);
}
void timer_handler_0 (int signum)
{
static int count = 0;
unsigned int clktime;
struct timespec res;
clock_gettime(CLOCK_MONOTONIC, &res);
clktime = res.tv_sec*1000+res.tv_nsec/1000000;
printf("%08d:%s]timer expired %d timers\n",clktime,__FUNCTION__, ++count);
}
void timer_handler_1 (int signum)
{
static int count = 0;
unsigned int clktime;
struct timespec res;
clock_gettime(CLOCK_MONOTONIC, &res);
clktime = res.tv_sec*1000+res.tv_nsec/1000000;
printf("%08d:%s]timer expired %d timers\n",clktime,__FUNCTION__, ++count);
}
void timer_handler_2 (int signum)
{
static int count = 0;
unsigned int clktime;
struct timespec res;
clock_gettime(CLOCK_MONOTONIC, &res);
clktime = res.tv_sec*1000+res.tv_nsec/1000000;
printf("%08d:%s]timer expired %d timers\n",clktime,__FUNCTION__, ++count);
}
void timer_handler_3 (int signum)
{
static int count = 0;
unsigned int clktime;
struct timespec res;
clock_gettime(CLOCK_MONOTONIC, &res);
clktime = res.tv_sec*1000+res.tv_nsec/1000000;
printf("%08d:%s]timer expired %d timers\n",clktime,__FUNCTION__, ++count);
}
timer_t myTimer(int id, void (*handler), int intms)
{
struct itimerspec its;
timer_t timerid;
struct sigevent sev;
sigset_t mask;
struct sigaction sa;
/* Establish handler for timer signal */
printf("Establishing handler for signal %d\n", SIGRTMIN+id);
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = handler;
sigemptyset(&sa.sa_mask);
if (sigaction(SIGRTMIN+id, &sa, NULL) == -1)
{
printf("sigaction error\n");
return (timer_t)-1;
}
/* Block timer signal temporarily */
printf("Blocking signal %d\n", SIGRTMIN+id);
sigemptyset(&mask);
sigaddset(&mask, SIGRTMIN+id);
if (sigprocmask(SIG_SETMASK, &mask, NULL) == -1)
{
printf("sigprocmask error\n");
return (timer_t)-2;
}
/* Create the timer */
sev.sigev_notify = SIGEV_SIGNAL;
sev.sigev_signo = SIGRTMIN+id;
sev.sigev_value.sival_ptr = &timerid;
if (timer_create(CLOCK_MONOTONIC, &sev, &timerid) == -1)
{
printf("timer_create error\n");
return (timer_t)-3;
}
printf("timer ID is 0x%lx\n", (long) timerid);
printf("Unblocking signal %d\n", SIGRTMIN+id);
if (sigprocmask(SIG_UNBLOCK, &mask, NULL) == -1)
{
printf("sigprocmask error\n");
return (timer_t)-5;
}
/* start the timer */
its.it_value.tv_sec = intms / 1000;
its.it_value.tv_nsec = (intms%1000) * 1000000;
its.it_interval.tv_sec = its.it_value.tv_sec;
its.it_interval.tv_nsec = its.it_value.tv_nsec;
if (timer_settime(timerid, 0, &its, NULL) == -1)
{
printf("timer_start error\n");
return (timer_t)-3;
}
return timerid;
}
int main ()
{
struct sigaction sa, sa1, sa2;
struct itimerval timer, timer1, timer2;
/* Install timer_handler as the signal handler for SIGVTALRM. */
memset (&sa, 0, sizeof (sa));
sa.sa_handler = &timer_handler;
sigaction (SIGRTMIN+0, &sa, NULL);
memset (&sa1, 0, sizeof (sa1));
sa1.sa_handler = &timer_handler_1;
sigaction (SIGRTMIN+1, &sa, NULL);
//sigaction (SIGALRM, &sa1, NULL);
memset (&sa2, 0, sizeof (sa2));
sa2.sa_handler = &timer_handler_2;
sigaction (SIGRTMIN+2, &sa, NULL);
//sigaction (SIGALRM, &sa2, NULL);
/* Configure the timer to expire after 250 msec... */
timer.it_value.tv_sec = 0;
timer.it_value.tv_usec = 250000;
/* ... and every 250 msec after that. */
timer.it_interval.tv_sec = 0;
timer.it_interval.tv_usec = 250000;
/* Configure the timer to expire after 900 msec... */
timer1.it_value.tv_sec = 0;
timer1.it_value.tv_usec = 900000;
/* ... and every 900 msec after that. */
timer1.it_interval.tv_sec = 0;
timer1.it_interval.tv_usec = 900000;
/* Configure the timer to expire after 1800 msec... */
timer2.it_value.tv_sec = 1;
timer2.it_value.tv_usec = 800000;
/* ... and every 1800 msec after that. */
timer2.it_interval.tv_sec = 1;
timer2.it_interval.tv_usec = 800000;
/* Start a virtual timer. It counts down whenever this process is executing. */
// setitimer (ITIMER_REAL, &timer, NULL);
// setitimer (ITIMER_REAL, &timer1, NULL);
// setitimer (ITIMER_REAL, &timer2, NULL);
myTimer(1, timer_handler_0, 600);
myTimer(2, timer_handler_1, 900);
myTimer(3, timer_handler_2, 1200);
myTimer(4, timer_handler_3, 1500);
/* Do busy work. */
while (1);
}
结果::
kt.ahn@Linux:~/work/test_c_code$ ./alarmtest
Establishing handler for signal 35
Blocking signal 35
timer ID is 0xb8b010
Unblocking signal 35
Establishing handler for signal 36
Blocking signal 36
timer ID is 0xb8b030
Unblocking signal 36
Establishing handler for signal 37
Blocking signal 37
timer ID is 0xb8b050
Unblocking signal 37
Establishing handler for signal 38
Blocking signal 38
timer ID is 0xb8b070
Unblocking signal 38
2060673821:timer_handler_0]timer expired 1 timers
2060674121:timer_handler_1]timer expired 1 timers
2060674421:timer_handler_0]timer expired 2 timers
2060674421:timer_handler_0]timer expired 2 timers
2060674421:timer_handler_2]timer expired 1 timers
2060674721:timer_handler_3]timer expired 1 timers
2060675021:timer_handler_0]timer expired 3 timers
2060675021:timer_handler_0]timer expired 3 timers
2060675021:timer_handler_1]timer expired 2 timers
2060675621:timer_handler_0]timer expired 4 timers
2060675621:timer_handler_2]timer expired 2 timers
2060675921:timer_handler_1]timer expired 3 timers
2060676221:timer_handler_0]timer expired 5 timers
2060676221:timer_handler_3]timer expired 2 timers
2060676821:timer_handler_0]timer expired 6 timers
2060676821:timer_handler_0]timer expired 6 timers
2060676821:timer_handler_2]timer expired 3 timers
2060676821:timer_handler_1]timer expired 4 timers
2060677421:timer_handler_0]timer expired 7 timers
^C
关于c - 自问自答,利用系统信号制作Linux单调定时器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28213478/