有三种可以使用
//参考如下链接
https://blog.csdn.net/vanturman/article/details/84131324
#include
#include
#include
#include
void handler(int sig) {
printf("this is handler function!\n");
exit(0);
}
int main(int argc, char **argv) {
signal(SIGALRM, handler);
alarm(1);
sleep(5);
printf("hello world!\n");
return 0;
}
程序分析:在文件alarm_test_1.c中,定义了一个时钟alarm(5),它的作用是让信号SIGALRM在经过5秒后传送给目前main()所在进程;接着又定义了sleep(1),它的作用是让执行挂起1秒的时间。所以当main()程序挂起1秒钟时,signal函数调用SIGALRM信号的处理函数sig_alarm,并且sig_alarm输出并执行exit(0)使得程序直接退出。因此,printf(“hello world!\n”)语句是没有被执行的。
#include
#include
#include
#include
void handler(int sig) {
printf("this is handler function!\n");
exit(0);
}
int main(int argc, char **argv) {
signal(SIGALRM, handler);
alarm(5);
sleep(1);
printf("hello world!\n");
return 0;
}
程序分析:与上一个测试不同的是,在本测试代码中延时函数为sleep(1),即执行挂起5秒的时间。所以当main()程序挂起1秒钟时,由于还没到达设置的闹钟5秒,那么main就执行下面的printf(“hello world!\n”)语句;紧接着又执行下面的return 0语句,从而直接退出程序。因此,本次输出的内容为:hello world!。
#include
#include
#include
#include
void handler(int sig) {
printf("hello, this is signal %d\n", sig);
}
int main(int argc, char **argv) {
signal(SIGALRM, handler);
alarm(5);
for (int i = 1; i < 7; ++i) {
sleep(1);
printf("sleep %d secs.\n", i);
}
return 0;
}
程序分析:在文件alarm_test_2.cpp中,定义时钟alarm(5),而main()函数中主要是一个for循环输出语句。当main函数执行到i=5时,for循环先执行sleep(1)语句,此时已经到达闹钟时间5秒,因此会把信号SIGALRM传送给当前main()函数进程;接着调用SIGALRM信号的处理函数handler,从而输出"hello",然后for循环中输出这个点printf(“sleep %d secs.\n”, i)语句输出"sleep 5 …";最后for循环执行i=6,输出"sleep 6",最终结束整个程序。
以上三个程序都只包含一个alarm()闹钟函数,下面两个程序包含两个alarm()。并且为了更为真切的观察包含alarm()闹钟函数的程序的执行过程,程序通过调用系统打印输出当前时间,通过时间差来进一步理解。
#include
#include
#include
#include
void handler(int sig) {
system("date");
return;
}
int main(int argc, char **argv) {
signal(SIGALRM, handler);
system("date");
alarm(10);
sleep(5);
printf("%d\n", alarm(1));
pause();
return 0;
}
程序分析:在alarm_test_3.cpp的main()函数中,先设置了一个闹钟函数alarm(10),即在10秒时将SIGALRM信号传送送给当前进程;然后又定义了一个延时函数sleep(5),接着又定义了一个闹钟函数alarm(1),它的作用是清除前面设置的闹钟alarm(10)并返回剩余的时间10-5=5秒。所以,程序先执行system(“date”)语句输出当前时间;然后进程休眠5秒后,程序执行输出语句printf("%d\n",alarm(1)),由于alarm(1)先返回5秒,即打印输出5;接着程序执行pause()函数,使当前进程处于挂起状态,直到捕捉到一个信号;当再过1秒后,SIGALARM信号的处理函数sig_alrm执行system(“date”)语句输出当前时间;最后pause终止进程。因此,整个程序执行的时间为5+1=6秒。
#include
#include
#include
#include
#include
#include
int count[4] = {0};
void set_timer()
{
//设置为1秒钟调用一次
struct itimerval itv, oldtv;
itv.it_interval.tv_sec = 1;
itv.it_interval.tv_usec = 0;
itv.it_value.tv_sec = 1;
itv.it_value.tv_usec = 0;
setitimer(ITIMER_REAL, &itv, &oldtv);
}
void sigalrm_handler(int sig)
{
count[0]++;
count[1]++;
count[2]++;
count[3]++;
//timer_30s++;
//printf("timer signal.. %d\n", count);
}
void * fpga_thread(void *arg)
{
char port_no = *(char*)arg;
while(1)
{
if(count[port_no] == 5)
{
printf("timer port_no\r\n",port_no);
}
//实际使用中可以设置多个定时器,例如 5秒定时,处理。如上。
//例 30s定时
// if timer_30s == 30
// handle code is here.
// timer_30s = 0;
usleep(1000); //延迟1ms为了让出cpu。
}
}
int main()
{
pthread_t th;
int i;
//给定时器设置了句柄函数,定时器超时,会调用该函数
signal(SIGALRM, sigalrm_handler);
//设置定时器调用该句柄函数的间隔时长
set_timer();
//常见4个线程
for(i=0;i<4;i++)
{
pthread_create(&th,NULL,fpga_thread,i);
}
while(1)
{
sleep(1); //同样是为了让出cpu
}
}
gcc -o tests tests.c -lpthread
程序分析:
程序中只起了一个定时器,linux应该只能支持这一个定时器,要在多个线程中使用,就要设置多个,每个线程中使用不同的,例如上边程序中count[] 数组四个分别模拟4个timer,相当于每个线程使用一个timer,各timer之间独立,不互相打扰。
main()
{
while(1)
{
//业务处理代码
if(timer >=60)
{
//每60s处理一次
timer = 0;
}
sleep(1);
timer++
}
}
上边代码示例,因为业务处理代码很有可能也有一些延时,这样会造成60s是不准的,实际的时间长度会超过60s。如果使用select,能让时间准确一些。(标注:感觉也不一定)
main()
{
struct timeval tv;
tv.tv_sec= 1;
tv.tv_usec= 0;
int err;
do{
err = select(0,NULL,NULL,NULL,&tv);
if(timer == 60){
此处写业务处理代码,能保证60s的业务处理时间是准确的。
}
timer++
}while(err<0)
}
按我当前遇到的问题,使用settimer和select都可以,但似乎select用在我的程序里做改造更加的方便。
由于时间紧,文章写的比较简略,以后在做完善。