English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Timer Timer has a very wide range of applications, in Linux, there are the following methods:
1, using sleep() and usleep()
where the accuracy of sleep is1seconds, the accuracy of usleep is1Subtle, the specific code is not written here. The disadvantage of this method is quite obvious, in the Linux system, sleep-like functions cannot guarantee accuracy, especially when the system load is large, and sleep generally has a timeout phenomenon.
2, using the semaphore SIGALRM + alarm()
The accuracy of this method can reach1seconds, where*The semaphore mechanism of the nix system, first register the semaphore SIGALRM handler, call alarm(), set the timing length, the code is as follows:
#include <stdio.h> #include <signal.h> void timer(int sig) { if(SIGALRM == sig) { printf("timer\n"); alarm(1); //we continue to set the timer } return ; } int main() { signal(SIGALRM, timer); //relate the signal and function alarm(1); //trigger the timer getchar(); return 0; }
Although the alarm method is good, it cannot be less than1with second precision.
3, using the RTC mechanism
The RTC mechanism utilizes the Real Time Clock mechanism provided by the system hardware, by reading the RTC hardware/dev/RTC, set the RTC frequency through ioctl(), the code is as follows:
#include <stdio.h> #include <linux/rtc.h> #include <sys/ioctl.h> #include <sys/time.h> #include <sys/types.h> #include <fcntl.h> #include <unistd.h> #include <errno.h> #include <stdlib.h> int main(int argc, char* argv[]) { unsigned long i = 0; unsigned long data = 0; int retval = 0; int fd = open("/dev/rtc", O_RDONLY); if(fd < 0) { perror("open"); exit(errno); } /*Set the freq as 4Hz*/ if(ioctl(fd, RTC_IRQP_SET, 1) < 0) { perror("ioctl(RTC_IRQP_SET)"); close(fd); exit(errno); } /* Enable periodic interrupts */ if(ioctl(fd, RTC_PIE_ON, 0) < 0) { perror("ioctl(RTC_PIE_ON)"); close(fd); exit(errno); } for(i = 0; i < 100; i++) { if(read(fd, &data, sizeof(unsigned long)) < 0) { perror("read"); close(fd); exit(errno); } printf("timer\n"); } /* Disable periodic interrupts */ ioctl(fd, RTC_PIE_OFF, 0); close(fd); return 0; }
This method is more convenient, it uses the RTC provided by the system hardware, the precision can be adjusted, and it is very high.
4, using select()
This method is seen in the APUE master book, the method is relatively rare, it uses select() to set the timer; the principle is to use the select() method's5A parameter, the first parameter is set to 0, and the three file descriptor sets are all set to NULL, the5A parameter is a time structure, the code is as follows:
#include <sys/time.h> #include <sys/select.h> #include <time.h> #include <stdio.h> /*seconds: the seconds; mseconds: the micro seconds*/ void setTimer(int seconds, int mseconds) { struct timeval temp; temp.tv_sec = seconds; temp.tv_usec = mseconds; select(0, NULL, NULL, NULL, &temp); printf("timer\n"); return ; } int main() { int i; for(i = 0 ; i< 100; i++) setTimer(1, 0); return 0; }
This method can achieve microsecond level precision, and there are many multi-threaded timers based on select() on the Internet, indicating that the stability of select() is still very good.
Summary:If the system requirements are low, you can consider using simple sleep(), after all, a single line of code can solve the problem; if the system has high precision requirements, then you can consider RTC mechanism and select() mechanism.
This is the summary of several methods to implement timers under Linux, brought to you by the editor. I hope everyone will support and cheer for the tutorial~