Linux 9 定时器

笔记

1.sleep()实现定时器,精度为1s

2.usleep()实现定时器,精度为1us

3.select实现定时器
通过timeval 中的tv_sec 和tv_usec 设置定时间隔

4.通过alarm()产生SIGALRM 信号,捕捉SIGALRM 信号实现定时器,alarm参数为定时时长
设置信号处理函数signal(SIGALRM , proc);

5.用settimer实现定时器
int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue));
which决定产生哪种信号:
ITIMER_REAL:以系统真实的时间来计算,它送出SIGALRM信号
ITIMER_VIRTUAL:以该进程在用户态下花费的时间来计算,它送出SIGVTALRM信号
ITIMER_PROF:以该进程在用户态下和内核态下所费的时间来计算,它送出SIGPROF信号
这里用ITIMER_REAL,产生SIGALRM信号,同样使用信号处理函数signal(SIGALRM , proc)

6.使用RTC实现定时器,精度较高
位于/dev/rtc

用例
/* timer.c */

#include <unistd.h>  
#include <stdlib.h>  
#include <stdio.h>  
#include <signal.h>  
#include <sys/time.h>  
#include <sys/select.h>  
#include <time.h>
#include <linux/rtc.h>  
#include <sys/ioctl.h>
#include <fcntl.h> 

#define ALARM_TIMER

int sigCount = 0;

void sigTimer(int sig)
{
    if (SIGALRM == sig)
    {

    	sigCount++;
    	
    	#ifdef ALARM_TIMER
    	printf("timer signal SIGALRM by alarm()\r\n");
    	alarm(1);	/* 继续设置定时器 */
    	#else
    	printf("timer signal SIGALRM by setitimer()\r\n");
    	#endif
    }
}

int main()  
{   
    int i = 0;
    struct timeval timeVal;	/* select使用的参数结构体 */
    int fd = -1;
    unsigned long data = 0;
    struct itimerval tick = {0};	/* setitimer使用 */
    
    /* sleep(单位s)实现定时 */
    for (i = 0; i < 5; i++) 
    {   
        printf("timer by sleep(1) function\r\n");   
        sleep(1);
    }  
    
    /* usleep(单位us)实现定时 */
    for (i = 0; i < 5; i++) 
    {   
        printf("timer by usleep(1000000) function\r\n");   
        usleep(100000);
    }  
    
    /* select实现定时器功能 */
    for (i = 0; i < 5; i++) 
    { 
        timeVal.tv_sec = 1;				/* 设置时间s */
        timeVal.tv_usec = 500000;	/* 秒后面的零头,单位微秒 */
        
        select(0, NULL, NULL, NULL, &timeVal);
        printf("timer by select function\r\n");
    }
    
    /* 使用SIGALRM和alarm完成定时器功能 */
    signal(SIGALRM , sigTimer);	/* 设置信号处理函数 */
    #ifdef ALARM_TIMER
    alarm(1);	/* 触发产生SIGALRM信号,设置定时长度为1s */
    while(1)
    {
        if (5 == sigCount)
        	break;
    }
    #endif
    
    /* 使用RTC实现定时器,精度较高 */
    fd = open("/dev/rtc", O_RDONLY);
    if (fd < 0)
    {
        perror("open");
    }
    else
    {
        ioctl(fd, RTC_IRQP_SET, 1);	/* 设置频率1HZ */
        ioctl(fd, RTC_PIE_ON, 0);		/* 开启定时器中断 */
        for (i = 0; i < 5; i++)
        {
            if(read(fd, &data, sizeof(unsigned long)) < 0)
            {
                perror("read");
                close(fd);		
            }
            printf("timer by RTC(real timer clock)\r\n");
        }
        ioctl(fd, RTC_PIE_OFF, 0);	/* 关闭定时器中断 */
        close(fd);
    }
    
    /*
    int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue)); 
    which决定产生哪种信号:
    ITIMER_REAL:以系统真实的时间来计算,它送出SIGALRM信号
    ITIMER_VIRTUAL:以该进程在用户态下花费的时间来计算,它送出SIGVTALRM信号
    ITIMER_PROF:以该进程在用户态下和内核态下所费的时间来计算,它送出SIGPROF信号
    */
    //Timeout to run first time
    tick.it_value.tv_sec = 1;
    tick.it_value.tv_usec = 0;

    //After first, the Interval time for clock
    tick.it_interval.tv_sec = 1;
    tick.it_interval.tv_usec = 0;
    
    #ifndef ALARM_TIMER
    setitimer(ITIMER_REAL, &tick, NULL);
    while(1)
    {
        if (5 == sigCount)
        	break;
    }
    #endif
    
    exit(EXIT_SUCCESS);  
}  

makefile:


APP_NAME = timer
APP_OBJS = timer.o

CC = gcc
INC = ./
CFLAG += -g

.PHONY : all

all : $(APP_NAME)

$(APP_NAME) : $(APP_OBJS)
	$(CC) $(CFLAG) $(APP_OBJS) -o $(APP_NAME)
	
%.o : %.c
	$(CC) -c $(CFLAG) $^ -o $@

.PHONY : clean

clean :
	rm -f *.o
	rm -f $(APP_NAME)

猜你喜欢

转载自blog.csdn.net/zzj244392657/article/details/92567762
今日推荐