There are two types of timers in Linux:
1. Alarm
Alarm () and signal () are enough if they are not required to be accurate.
Unsigned int alarm (unsigned int seconds)
Specifically set for the sigalrm signal. After the specified time is seconds, the sigalrm signal will be sent to the process itself, also known as the alarm time. After a process calls alarm, any previous alarm () call will be invalid. If the seconds parameter is zero, no alert time is included in the process. If the alarm time has been set in the process before calling alarm (), the remaining time of the previous alarm time is returned; otherwise, 0 is returned.
Example:
# Include <stdio. h>
# Include <unistd. h>
# Include <signal. h>
Void sigalrm_fn (INT sig)
{
/* Do something */
Printf ("alarm! /N ");
Alarm (2 );
Return;
}
Int main (void)
{
Signal (sigalrm, sigalrm_fn );
Alarm (2 );
/* Do someting */
While (1) pause ();
}
2. setitimer
Int setitimer (INT which, const struct itimerval * value, struct itimerval * ovalue ));
Setitimer () is more powerful than alarm and supports three types of Timers:
Itimer_real: calculated based on the real time of the system. It sends the sigalrm signal.
Itimer_virtual: calculate based on the actual execution time of the trip, and it sends the sigvtalrm signal.
Itimer_prof: calculates the actual schedule and the time spent in the core. It sends a sigprof signal.
Setitimer () the first parameter which specifies the timer type (one of the above three); the second parameter is an instance of the structure itimerval; the third parameter can not be processed.
If setitimer () is called successfully, 0 is returned; otherwise,-1 is returned.
The following is a simple example of setitimer calling. In this example, a sigalrm is sent every second and a sigvtalrm signal is sent every 0.5 seconds ::
# Include <stdio. h>
# Include <stdlib. h>
# Include <unistd. h>
# Include <signal. h>
# Include <time. h>
# Include <sys/time. h>
Int sec;
Void sigroutine (INT signo ){
Switch (signo ){
Case sigalrm:
Printf ("catch a signal -- sigalrm/N ");
Signal (sigalrm, sigroutine );
Break;
Case sigvtalrm:
Printf ("catch a signal -- sigvtalrm/N ");
Signal (sigvtalrm, sigroutine );
Break;
}
Return;
}
Int main ()
{
Struct itimerval value, ovalue, value2;
SEC = 5;
Printf ("process ID is % d", getpid ());
Signal (sigalrm, sigroutine );
Signal (sigvtalrm, sigroutine );
Value. it_value. TV _sec = 1;
Value. it_value. TV _usec = 0;
Value. it_interval. TV _sec = 1;
Value. it_interval. TV _usec = 0;
Setitimer (itimer_real, & Value, & ovalue );
Value2.it _ value. TV _sec = 0;
Value2.it _ value. TV _usec = 500000;
Value2.it _ interval. TV _sec = 0;
Value2.it _ interval. TV _usec = 500000;
Setitimer (itimer_virtual, & value2, & ovalue );
For (;;)
;
}
The Screen Copy in this example is as follows:
Localhost :~ $./Timer_test
Process ID is 579
Catch a signal-sigvtalrm
Catch a signal-sigalrm
Catch a signal-sigvtalrm
Catch a signal-sigvtalrm
Catch a signal-sigalrm
Catch a signal-gvtalrm
Note: The Linux signal mechanism is basically inherited from UNIX systems. In early Unix systems, the signal mechanism was relatively simple and original, and some problems were exposed in practice. Therefore, the signals built on the early mechanism were called "unreliable signals ", signals smaller than sigrtmin (in Red Hat 7.2, sigrtmin = 32, sigrtmax = 63) are unreliable signals. This is the source of "unreliable signal. The main problem is that each time a process processes a signal, it sets the response to the signal as the default action. In some cases, it may lead to incorrect signal processing. Therefore, if you do not want such an operation, you need to call signal () again at the end of the signal processing function (), reinstall the signal.