Linux time types, functions, and sleep functions

Source: Internet
Author: User
Tags epoch time local time posix sleep function usleep

Reprint Please specify Source:

This article mainly deals with Linux time types, time functions, and sleep functions provided by Linux.

the time type and the corresponding function: time_t:

The most unfamiliar time type is probably the time_t type. It appears in the standard library of the C language. However, ISO C does not specify what type, range, and precision the time_t is, but is generally implemented as a signed integer in POSIX.

The unit of time_t is seconds. The return value of the function time () is a time_t type that represents the number of seconds from 1970-01-01 00:00:00 UTC (that is, epoch time) to now. Note that the function returns a UTC time, not the Beijing time we normally use. You can use the function localtime to convert this UTC time into local time. We can use this function to convert UTC time into Beijing time. The return value of localtime is a struct TM struct pointer. Defined as follows:

struct TM {int tm_sec;    /* seconds [0-60] have leap seconds */int tm_min;    /* min [0-59] */int tm_hour;   /* hours [0-23] */int tm_mday;   /* Day [1-31] */int Tm_mon;    /* Month [0-11] */int tm_year;   /* year whose value equals the year-1900 */int Tm_wday;   /* Week]0-6] Sunday for 0 */int Tm_yday;   /* Today is the day of the year [0-365]  January 1 is the No. 0 day of */int tm_isdst;  /* Daylight saving time flag bit */};

Pay attention to the scope of each member, and don't make a mistake. In addition, for the second, there is a leap second. So the range is [0, 60].

As you can see, the members of this struct TM struct are useful relative to a time_t. Because a given time_t, people simply do not know which time it represents, but converted to a struct TM structure can see at a glance what time it is.

If you do not want to convert time to cost time and simply convert to a struct TM, you can use the function gmtime, which also returns a struct TM pointer. Because both LocalTime and gmtime return a pointer, they are not thread-safe. For the ground, there are localtime_r and Gmtime_r. This two function is thread-safe. If you convert a struct TM time to time_t, you can use the Mktime function. Sometimes you want to convert the time type to a string for easy output, and the standard C language also provides these functions. The declarations for these functions are given below.

Char *asctime (const struct TM *tm), char *asctime_r (const struct TM *tm, Char *buf); char *ctime (const time_t *TIMEP); char * Ctime_r (const time_t *TIMEP, char *buf), struct TM *gmtime (const time_t *TIMEP), struct TM *gmtime_r (const time_t *TIMEP, St Ruct TM *result), struct TM *localtime (const time_t *TIMEP), struct TM *localtime_r (const time_t *TIMEP, struct TM *result); time_t mktime (struct TM *tm);

In general, these functions are in the Time.h header file. But for the thread-safe functions, some compilers have to #include<pthread.h> the other.


Its actual type is a signed integer, which is typically used to indicate the CPU time consumed by a process. The function clock () returns the value of a clock_t type, indicating how much CPU time is used by the process from startup to calling the clock function. By dividing the return value by Clocks_per_sec, you can get the time in seconds. The clock function is declared in the time.h header file.

struct Timeval:

Relatively speaking, the grain size of the time_t is still relatively large, the unit is seconds.

Linux also offers one of the following additional precision types strut timeval.

struct Timeval {time_t      tv_sec;     /* seconds */suseconds_t tv_usec;    /* microseconds microseconds */};

Member Tv_usec represents microseconds, 1 seconds = 1 000 milliseconds = 1 000 000 microseconds.

This is typically used in the function Gettimeofday function to this time type.

#include <syt/time.h>int gettimeofday (struct timeval *tv, struct timezone *tz);//The second parameter is generally null

Like the time function language, it also returns a period from 1970-01-01 00:00:00 UTC (That is, the epoch time) to the present, which is, of course, the system time, which is not local time for UTC time. struct Timeval can also be used as the current time, the member tv_sec with the above localtime conversion can be.

Linux also defines a series of operational functions for struct timeval. For example, add and subtract, empty, compare.

#include <sys/time.h>void timeradd (struct timeval *a, struct timeval *b, struct timeval *res);//res = a + bvoid time Rsub (struct timeval *a, struct timeval *b, struct timeval *res);//res = a-bvoid timerclear (struct timeval *TVP); int time Risset (struct timeval *TVP); int timercmp (struct timeval *a, struct timeval *b, CMP);

The parametric CMP is our usual comparison symbol <, >=,! =, and so on.

One thing to note is that because Gettimeofday gets the time of the system. Because the user is able to manually modify the system time. So the time that gettimeofday gets may be the wrong time.

If the program wants to get the system separately at two different times, then calculate the time difference. Then the Gettimeofday function is not the best choice. The reason is that the user can modify the system time. You should use monotonic time at this point. Monotonic time is the boot boot to the present time, no one can modify it. This monotonic time will be explained below.

struct Timespec:
struct Timespec {time_t   tv_sec;        /* seconds */long     tv_nsec;       /* nanoseconds nanoseconds */};

The time accuracy it can provide is nanosecond. Of course, hardware does not necessarily support this accuracy. There are three functions associated with it.

glibc2.17 versions prior to the link need to be added-lrt#include <time.h>int clock_getres (clockid_t clk_id, struct timespec *res); int Clock_ GetTime (clockid_t clk_id, struct timespec *tp); int Clock_settime (clockid_t clk_id, const struct TIMESPEC *tp);

You can view the version of glibc with the ls-al/lib/ or ldd–version command, and theuname-r command to view the Linux kernel version.

The parameter clk_id represents the clock type, and Linux provides these clock types.

    • Clock_realtime: System-wide real-time clock. System scope refers to all users of the system that are used by all programs. The real-time clock refers to the current time of the system (just like the time in the lower right corner of Windows), which is the same as the system time obtained by the Gettimeofday function. System time is modifiable, so you can use Clock_settime (clock_realtime) to modify the system's time
    • Clock_realtime_coarse: A clock_realtime that is faster but time-granular (that is, time accuracy is not so high). This function is unique to the Linux system and appears for the first time in the 2.6.32 kernel version
    • Clock_monotonic:monotonic time. Monotonic is monotonous, meaning that it is only monotonically increasing and cannot be manually modified by others . POSIX just shows that it is a monotonous time, and does not specify a monotonic time from when to start counting. So some systems take the epoch time, and some systems (like Linux) take the boot boot time. But it does not affect its own meaning.
    • Clock_monotonic_coarse: A clock_monotonic that is faster but time-granular (that is, time accuracy is not so high). This function is unique to the Linux system and appears for the first time in the 2.6.32 kernel version
    • Clock_boottime: Same as Clock_monotonic, only when the system is suspended, it will be timed (clock_monotonic not)
    • CLOCK_PROCESS_CPUTIME_ID: How much CPU time the process uses. The CPU time used by all threads in the process is counted
    • CLOCK_THREAD_CPUTIME_ID: How much CPU time is used by the thread

The Clock_getres function is used to obtain the time accuracy that the corresponding clock type can provide, and the res parameter preserves its accuracy. When set, the set time value should also be a multiple of this accuracy. Some of the following sleep functions also use these clock types, and the sleep time should also be a multiple of the accuracy, otherwise the sleep function truncates the multiplier. such as the Nanosleep function.

The function clock_gettime is used to get the corresponding clock time. The function clock_settime is used to set the time of the corresponding clock. Some clocks are not allowed to be set.

Sleep function:

Linux provides a sleep function with different time accuracy. Some of these functions appear in the Linux high version, and some are non-thread safe. The following is a detailed description of each sleep function.

#include <unistd.h>unsigned int sleep (unsigned int seconds);

From the parameter name of sleep, you can see that the function's sleep time unit is seconds. Since this sleep function may be interrupted by external signals, it has a return value that indicates the rest of the sleep time. If the time specified by the parameter lock is not interrupted by the signal, then 0 is returned.

Since the sleep function may be implemented using signal SIGALRM, you should not use the alarm function while using the sleep function. In fact, in the UNIX environment advanced programming, also see in the book there is an example of how to implement the Sleep function, in which the method is alarm.

Obviously, if sleep is implemented with SIGALRM, then it is certainly not thread-safe.

note that a sleep function (s is uppercase) is provided in Windows, and its time unit is milliseconds.

#include <unistd.h>int usleep (useconds_t usec);//microseconds

The time granularity of the usleep sleep function is small, is microseconds, enough. And the function is thread-safe.

When this sleep function is not interrupted to hibernate the specified time, it will return 0. If the signal is interrupted, it returns-1, and the errno is set to Eintr. If the specified parameter is not less than 1000000, it will also return-1, which considers the sleep time to be too long, at which time the errno is set to Einval.

If you want to use this function, then the version of GLIBC is either less than 2.12. You can view the version of glibc with the command ls-al/lib/ .

#include <time.h>int nanosleep (const struct TIMESPEC *req, struct timespec *rem);//nanoseconds

The Nanosleep function provides a nanosecond-level sleep time. That's pretty good. The parameter req indicates the time to hibernate. If the specified time is successfully dormant, 0 is returned.

If hibernation is interrupted by a signal, the return -1,errno is assigned the value EINTR. REM is assigned to the rest of the sleep time if the parameter REM is not NULL. With REM, even if interrupted by a signal, you can continue to hibernate until the specified sleep time begins. Although this method is theoretically feasible, time drift may actually occur. For example, you want to sleep 30ms, after 10ms, was interrupted by a signal. At this point REM will get the remaining value of 20ms. If the CPU performs a signal processing function that uses 10ms, then sleeps the time indicated by REM. In this way the time drift occurs, altogether sleeps 40ms. You can avoid this problem with clock_nanosleep because it can use absolute time.

The value of the TV_NSEC member of the Req range is 0 to 999999999. If it is a different value, the function directly returns -1,errno set to Einval.

POSIX.1 Specifies that Nanosleep uses the Clock_realtime clock to detect time (that is, if the detection is timed out). Linux, however, uses the Clock_monotonic clock. It looks like the Linux approach is sensible because the user is already said to be able to modify the Clock_realtime clock by calling the Clock_settime function. However, POSIX.1 also specifies that modifying the clock_realtime clock does not affect the use of nanosleep functions. Obviously to do this, the code is a bit more complicated. Use the Clock_monotonic clock without considering this problem.

glibc2.17 versions prior to the link need to be added-lrt#include <time.h>int clock_nanosleep (clockid_t clock_id, int flags,   const struct Timespec *request,   struct timespec *remain);

The parameter clock_id indicates which clock the function uses to detect if there is enough sleep. There are three selectable clocks of Clock_realtime, Clock_monotonic and clock_process_cputime_id. These times have been explained above and there is not much to say.

The parameter flags indicates that the use is not absolute time. If the value is 0, a time period (that is, the length of sleep) is used. If the parameter is set to Timer_abstime, then absolute time is used.

The parameter request indicates the sleep time. The parameter flags indicates whether this is a time period or an absolute time.

The function of the parameter remain is the same as the REM parameter of the previous Nanosleep function. When flags indicates that the request is a time period and the function is interrupted by a signal, remain will get the rest of the sleep time. This parameter can be null.

If flags specifies that absolute time is used, and the time specified by the request is less than or equal to the current time, then the Clock_nanosleep function returns immediately and does not enter hibernation.

When Clock_nanosleep successfully sleeps for the specified time, it will return 0. Otherwise, the error value is returned, not set errno variable. This is different from other sleep functions. The following error values are available.

Fault:request or remain points to an illegal address (that is, the wild pointer)

Eintr: This function is interrupted by the signal function.

The range of TV_NSEC members of Einval:request is not 0 to 999999999, that is, it is an illegal value. When clock_id is not going to the three values mentioned above, it will also return einval. Note: Clock_nanosleep does not support clock_thread_cputime_id.

Some questions to note about this function: because the function can use the Clock_realtime clock and the clock can be manually modified. This may affect the Clock_nanosleep function. First, if the flags indicate a time period, then the Clock_nanosleep and Nanosleep functions have no effect.

If the user modifies the value of the Clock_realtime clock, it is bound to have an impact on the clock_nanosleep that is taking advantage of the clock for sleep.

the use of this function requires that the Linux kernel version is not less than 2.6,GLIBC version less than 2.1

In addition to the normal sleep function above, you can also use other functions to achieve sleep.

#include <sys/select.h> #include <sys/types.h>int select (int Nfds, fd_set *readfds, Fd_set *writefds,           Fd_set *exceptfds, struct timeval *timeout);

The last parameter of the Select function is a time value. Of course it is a time period, not an absolute time. When we need to use Select as a sleep function, set the previous four parameters to 0 directly.

If the specified time is dormant, the function returns 0. If the signal is interrupted halfway, then the return -1,errno is set to Eintr. Unlike other sleep functions, there is no portable method to know the rest of the sleep time. While some Linux modifies the timeout parameter, the remaining sleep time is obtained.

#include <poll.h>int poll (struct POLLFD *fds, nfds_t nfds, int timeout);

Setting the previous two parameters to 0,poll becomes a sleep function. The sleep time specified by the parameter timeout is also a time period, and its time unit is milliseconds.

If the specified time is dormant, the function returns 0. If the signal is interrupted halfway through, then the return -1,errno is set to Eintr.

Sleep time accuracy:

By some of the sleep functions listed above, Linux provides sleep functions of various time accuracy: sleep (Second level), poll (millisecond), Usleep (microsecond), Nanosleep (nanosecond).

common problems with sleep functions:

The sleep function is a problem, that is, the specified time cannot be really accurately dormant. There are two main reasons for this.

    1. The accuracy of the time provided by the system is insufficient. For example, the system can only provide 10ms accuracy, but you want to hibernate 15ms. At this point the system can only set the real sleep time to 10ms or 20ms. Generally take up, that is, take 20ms
    2. CPU scheduling issues. While the thread's sleep time is up, it's going to wake up. But at this point the CPU is still busy with other things, there is no space to wake up the dormant thread. Then the dormant thread will also be inaccurate in the real time of sleep









"UNIX Network programming Volume One"

Linux time types, functions, and sleep functions

Related Article

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: 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.