Scheduled implementation in Linux

Source: Internet
Author: User
Tags usleep

Reprinted from: http://www.cnblogs.com/feisky/archive/2010/03/20/1690561.html

The purpose of using a timer is nothing more than to periodically execute a task, or to execute a task at a specified time. To achieve this goal, there are generally two common effective methods.

One is to use three internal Linux Timers: itime_real, itimer_virtual, itime_prof;

The other is to use sleep, the usleep function to sleep the process for a period of time;

In fact, another method is to use gettimeofday () and difftime () to calculate the time interval, and then execute a task when the time is reached, but this method is inefficient, therefore, it is not commonly used.

1. Timer provided by the system

The Linux operating system provides three internal timers for each process:

Itimer_real: for a specified time interval, this count is reduced according to the actual time. When the time interval is 0, the sigalrm signal is sent.

Itimer_virtual: for a given time interval, the count is reduced when the process is executed, and the sigvtalrm signal is sent when the time interval is 0.

Itimer_prof: given a time interval, when the process is executed or the system is scheduled for the process, the count is reduced. When the time reaches, The sigprof signal is sent, which is combined with itimer_virtual, it is often used to calculate the system kernel time and user time.

The functions used include:

# Include <sys/time. h>
 
Int getitimer (intwhich, structitimerval
* Value );
Int setitimer (intwhich, structitimerval * newvalue, structitimerval * oldvalue );

The data structures used include:
Strcut timeval
{
Long
TV _sec;
/* Seconds */
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 the time at which the task is executed, and it_value is used to save the time before the task is executed.
For example, if you set it_interval to 2 seconds (microsecond to 0), we set the it_value time to 2 seconds (microsecond to 0) at the beginning, it_value is reduced to 1. After 1 second, it_value is reduced by 1 and becomes 0. At this time, a signal is sent (indicating that the task can be executed when the time is reached ), in addition, the system automatically resets the it_value time to the it_interval value, that is, 2 seconds, and then recalculates the value.

Struct sigaction
{
Void (* sa_handler) (INT );
Void (* sa_sigaction) (INT, siginfo_t *, void *);
Sigset_t sa_mask;
Int sa_flags;
Void (* sa_restorer) (void );
};
Sa_handler is a pointer pointing to the signal processing function;

The main differences with the following two methods:
Because the system provides the timer itself, after the time is reached, the message is automatically sent to the Message Queue by the system;
The latter two are implemented by the user, so the process ID and signal ID must be transmitted to the Message Queue (implemented by the sigqueue () function ).

Procedure:

1. initialize the timer type and interval;

2. initialize the signal type and callback function;

3. When the set time is reached, the callback function is executed;

Example:

# Include <stdio. h> # include <signal. h> # include <sys/time. h> # include <string. h> # include <unistd. h> // The signal callback function void sign_proc (INT signo) {printf ("time is running out \ n");} // sets up the signal processing mechanism void init_sigaction () {struct sigaction signact; // specify the callback function signact after a signal is sent. sa_handler = sign_proc; signact. sa_flags = 0; // initialize the signal set sigemptyset (& signact. sa_mask); // specify the signal type. Ensure that the sigaction (sigalrm, & signact, null) is consistent with the timer type;} // set the timer void init_time () {struct itimerval interval; // initial value interval. it_value. TV _sec = 5; interval. it_value. TV _usec = 0; // interval. it_interval = interval. it_value; // set the timer type to itimer_real setimer (itimer_real, & interval, null);} int main () {init_time (); init_sigaction (); While (1 ); return 0 ;}

Note: The Program sets the timer type to Real-Time Timer: itmer_real, which sends a sigalrm signal every five seconds. When the main function receives the signal, it calls the signal processing function sign_proc for processing.

The usage of itimer_virtual and itimer_prof is similar. When you set the timer in setitimer to itimer_virtual, you change sigalrm in sigaction to sigvtalarm. Similarly, itimer_prof corresponds to sigprof.

2. Implement timing through sleep and usleep

# Include <signal. h> # include <unistd. h> # include <string. h> # include <stdio. h> void show_msg (INT signo) {printf ("time is using up \ n");} int main () {struct sigaction signact; Union sigval tsval; // set the signal callback function signact. sa_handler = show_msg; signact. sa_flags = 0; // initialize the signal set sigemptyset (& signact. sa_mask); sigaction (50, & signact, null); While (1) {sleep (2); sigqueue (getpid (), 50, tsval);} return 0 ;}

You can see that this is much simpler than the above, and you can test it with a stopwatch, the time is very accurate, specify 2 seconds to output a string for you. Therefore, this method is the easiest if you only perform a task at the regular time.

3. Timing by self-calculating the time difference

# Include <signal. h> # include <unistd. h> # include <string. h> # include <stdio. h> # include <time. h> void sign_proc (INT signo) {printf ("time is running out \ n");} int main () {struct sigaction signact; Union sigval tsval; // set the signal variable signact. sa_handler = sign_proc; signact. sa_flags = 0; sigemptyset (& signact. sa_mask); sigaction (50, & signact, null); time_t oldtime; time (& oldtime); While (1) {time_t nowtime; time (& nowtime ); if (nowtime-oldtime >=2) {// put the process ID and signal ID in the message mechanism sigqueue (getpid (), 50, tsval); oldtime = nowtime ;}}}

This method is less efficient and rarely used.

This is different from the above in that it is manually calculated by yourself. If you want to calculate the time difference more accurately, you can replace the time function with gettimeofday, which can be precise to the subtle.

The timing methods described above are different in terms of timing efficiency, method, and time accuracy. What method is used depends on your program needs.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.