The original text is from: http://hi.baidu.com/opetrhsxszbckzd/item/126966cae5f9524aa9ba94f5
I just repositioned it and labeled it.
linux c language timer
Summary:
The Linux timer is used to perform a task periodically or at a specified time.To achieve this goal, there are generally two common and more effective methods.One is to use three timers inside linux, the other is to use sleep, usleep function to let the process sleep for a period of time. In fact, there is another way to use gettimeofday, difftime, etc. to calculate the time interval themselves, and then execute a task when time is up, but this method is inefficient, so it is not often used.
Three timers inside Linux:
First, let's look at the three internal timers provided by the linux operating system for each process.
ITIMER_REAL: Gives a specified time interval to reduce this count by the actual time when the time interval is 0 and SIGALRM is signaled
ITIMER_VIRTUAL: Given an interval, decreases the count when the process executes, and signals SIGVTALRM when the interval is 0
ITIMER_PROF: Given a time interval, when a process executes or the system schedules a process, reduce the count, the time is up, and issue a SIGPROF signal, which, in conjunction with ITIMER_VIRTUAL, is often used to calculate system kernel time and user time.
The functions used are:
#include <sys/time.h> int getitimer(int which, struct itimerval *value); int setitimer(int which, struct itimerval*newvalue, struct itimerval* oldvalue); strcut timeval { long tv_sec; /*second*/ long tv_usec; /*Microseconds*/ }; struct itimerval { struct timeval it_interval; /*time interval*/ struct timeval it_value; /*Current Time Count*/ };
It_interval is used to specify how often a task is executed and it_value is used to save how long the current time is before the task is executed.For example, if you specify that it_interval is 2 seconds (microseconds are 0), we start by setting it_value to 2 seconds (microseconds are 0). After one second, it_value is reduced by 1, after another second, it_value is reduced by 1, then it_value is changed to 0, which signals (tells the user that time is up, you can be persistent)Row task), and the system automatically resets the time of it_value to the value of it_interval, which is 2 seconds, and counts again.
To help you understand this problem, let's take an example:
#include <sys/time.h> #include <stdio.h> #include <unistd.h> #include <signal.h> #include <string.h> static char msg[] = "time is running out\n"; static int len; // Output information to standard error telling user it's time void prompt_info(int signo) { write(STDERR_FILENO, msg, len); } // Set up signal processing mechanism void init_sigaction(void) { struct sigaction tact; /*Signaled to the task processing function to be executed as prompt_info*/ tact.sa_handler = prompt_info; tact.sa_flags = 0; /*Initialize Signal Set*/ sigemptyset(&tact.sa_mask); /*Set up signal processing mechanism*/ sigaction(SIGALRM, &tact, NULL); } void init_time() { struct itimerval value; /*Set a task execution interval of 2 seconds and 20 microseconds*/ value.it_value.tv_sec = 2; value.it_value.tv_usec = 0; /*Set the initial time count to 2 seconds 0 microseconds*/ value.it_interval = value.it_value; /*Set timer ITIMER_REAL*/ setitimer(ITIMER_REAL, &value, NULL); } int main() { len = strlen(msg); init_sigaction(); init_time(); while ( 1 ); exit(0); }
The ITMER_REAL timer of the program sends a SIGALRM signal every 2 seconds. When the main function receives the signal, the signal processing function prompt_info is called to output the time is running out string on the standard error.
The use of ITIMER_VIRTUAL is similar to that of ITIMER_PROF. When you set the timer in setitimer to ITIMER_VIRTUAL, you change the SIGALRM in sigaction to SIGVTALARM. Similarly, ITIMER_PROF corresponds to SIGPROF.
However, you may notice that when you use ITIMER_VIRTUAL and ITIMER_PROF, when you take a stopwatch, you will find that the program will output strings more than 2 seconds apart, or even 5-6 seconds apart. As to why, think about ^^ yourself
sleep, usleep function
Let's see how sleep and usleep can be used to perform tasks on a regular basis.
#include <signal.h> #include <unistd.h> #include <string.h> #include <stdio.h> static char msg[] = "I received a msg.\n"; int len; void show_msg(int signo) { write(STDERR_FILENO, msg, len); } int main() { struct sigaction act; union sigval tsval; act.sa_handler = show_msg; act.sa_flags = 0; sigemptyset(&act.sa_mask); sigaction(50, &act, NULL); len = strlen(msg); while ( 1 ) { sleep(2); /*Sleep for 2 seconds*/ /*Sending a signal to the main process is actually signaling itself*/ sigqueue(getpid(), 50, tsval); } return 0; }
See, this is much simpler than the one above, and when you measure it with a stopwatch, the time is precise and you can output a string when 2 seconds are specified.So if you're just on a regular schedule and it's time to perform a task, this is the easiest way to do it.
Let's look at timing by calculating the time difference yourself:
#include <signal.h> #include <unistd.h> #include <string.h> #include <stdio.h> #include <time.h> static char msg[] = "I received a msg.\n"; int len; static time_t lasttime; void show_msg(int signo) { write(STDERR_FILENO, msg, len); } int main() { struct sigaction act; union sigval tsval; act.sa_handler = show_msg; act.sa_flags = 0; sigemptyset(&act.sa_mask); sigaction(50, &act, NULL); len = strlen(msg); time(&lasttime); while ( 1 ) { time_t nowtime; /*Get the current time*/ time(&nowtime); /*When compared to the last time, if it is greater than or equal to 2 seconds, the signal is sent immediately*/ if (nowtime – lasttime >= 2) { /*Sending a signal to the main process is actually signaling itself*/ sigqueue(getpid(), 50, tsval); lasttime = nowtime; } } return 0; }
This differs from the above in that you calculate the time difference manually. If you want to calculate the time difference more accurately, you can change the time function to gettimeofday, which is precise and subtle.
Each of the timing methods described above has its own merits and differences in time efficiency, method and time accuracy, depending on the needs of your program.
Use of itimerval clock
#include<stdio.h> #include<signal.h> #Include<sys/time.h>//itimerval structure definition int handle_count=0; void set_time(void) { struct itimerval itv; itv.it_interval.tv_sec=10;//Load automatically and then respond every 10 seconds itv.it_interval.tv_usec=0; itv.it_value.tv_sec=5;//Time of First Timing itv.it_value.tv_usec=0; setitimer(ITIMER_REAL,&itv,NULL); } void alarm_handle(int sig) { handle_count++; printf("have handle count is %d\n",handle_count); } void main(void) { struct itimerval itv; signal(SIGALRM,alarm_handle); set_time(); while(1){ getitimer(ITIMER_REAL,&itv); printf("pass second is %d\n",(int)itv.it_value.tv_sec); sleep(1); } return; }
Reprinted at: https://www.cnblogs.com/fengty90/p/3768829.html