This article mainly introducesLinuxLow PrecisionTimeFunction, and related functions with a timeout mechanism.TimerIt also gives a brief introduction.
In linux, the most accurate time interface is gettimeofday. It returns a timeval structure with the precision of us (10-6 seconds). In most cases, this precision is enough. However, sometimes we need to explore the time calls provided by Linux for us for higher precision, such as the time precision of the nanoseconds.
First, we will introduce the struct timespec structure. This struct has two members: one is second and the other is nanosecond.
The librt Library provides high-precision time functions:
long clock_gettime(clockid_t ,struct timespec*)
Gets the time of a specific clock. The time is transmitted back through the fp structure. Currently, six clock types are defined, which are
The current time of the CLOCK_REALTIME system. The startup time of the CLOCK_MONOTONIC system is counted from 1970, January 1, 1.1. The high-precision version of CLOCK_REALTIME_HR CLOCK_REALTIME of CLOCK_MONOTONIC cannot be set.
Get the time precision of a specific clock:
long clock_getres(clockid_t )
Set the time of a specific clock:
long clock_settime(clockid_t ,struct timespec*)
The time specified in the sleep time. If a signal is interrupted and returned in advance, left_time returns the remaining time:
long clock_nanosleep(clockid_t ,int flag,timespec* time,timespec* left_time)
With these time functions, let's take a look at how to implement simple timers with different precision.
The most rough timer can be implemented by sleep, its precision is seconds, the system also provides such as nanosleep, usleep, ualarm, of course you are willing to also can be done by poll (MS) select (us), ppoll, or pslect (ns) to achieve sleep of various precision. With these high-precision sleep functions, you can also implement a system timer with different precision.
The timer implemented by sleep usually requires self-encoding, and too much sleep will make full use of a cpu. When there are a large number of timers, you need to carefully write the code, this method is usually used to check which timer expires by means of independent thread control or master loop polling. In general, the implementation is complex and inefficient, and there is no good notification mechanism for timer expiration, it is usually passively executed by the timer thread or its own thread checks and executes the expired timer in the main thread loop.
Next we will explore some timer mechanisms provided by the operating system. The operating system provides two types of timer, one is an explicit timer, and the other is hidden on the call timeout time or specific file attributes. We have seen the latter before. For example, the timeout attribute of select and socket descriptor must be accumulated in different programming fields. Of course, they also have their own precision. The following describes the explicit timer provided by the system.
The Linux system provides three interval timers for each process, with the precision of us. When the timer expires, the corresponding signal is triggered and the timer may start again. It is worth noting that the child process generated by fork does not inherit the timer of the parent process.
int getitimer(int type, itimerval* val) int setitimer(int type, itimerval* nval, itimerval* oval)
Itimerval has two members, it_interval and it_value, both of which are of the timeval type. The former stores the timer interval of the next timer, and the latter is the timer interval of the current timeout. That is to say, the timer will be reduced from it_value. When it is changed to 0, the timer will be sent, and the value from it_interval will start again. If val is set to 0, the timer is stopped.
Getitimer () is used to set a timer, while setitimer is used to modify the preset timer. If the timer has not timed out yet, the remaining time is saved in oval.
The three timers are:
ITIMER_REAL is decreased by system time, and the delivery of SIGALRM signal ITIMER_VIRTUAL is decreased by process execution time upon timeout. The delivery of SIGVTALRM ITIMER_PROF is decreased when the process is executed or the process is executed by the System Call upon timeout, deliver the SIGPROF signal upon timeout.
In addition, Posix1. B provides us with a real-time and high-precision timing tool, with a precision of up to nanoseconds. However, each process can only have one.
int timer_creat() int timer_delete() int timer_gettime() int timer_settime()
The specific usage is not described here. It can be seen that the timer provided by the system is a kind of cherished resource, which is usually the most basic facility. The application needs to use this basic facility to define a variety of timers, to enable the program to use multiple and multiple timers. Of course, the timer provided by the system requires manual signal processing and other related work, and requires special signal processing code, which increases the complexity of the program to a certain extent. Therefore, the timer of the sleep family has its own advantages and disadvantages from the timer of the system to the timer of the system. The timer should be weighed based on the situation.