轉載LYJ:http://blog.chinaunix.net/space.php?uid=14617649&do=blog&id=3058661
一、時間類型。Linux下常用的時間類型有4個:time_t,struct timeb, struct timeval,struct timespec,clock_t, struct tm.
(1) time_t是一個長整型,一般用來表示用1970年以來的秒數.
該類型定義在<sys/time.h>中.
一般通過 time_t time = time(NULL); 擷取.
(2) struct timeb結構: 主要有兩個成員, 一個是秒, 另一個是毫秒, 精確度為毫秒.
- struct timeb
- {
- time_t time;
- unsigned short millitm;
- short timezone;
- short dstflag;
- };
由函數int ftime(struct timeb *tp); 來擷取timeb.
成功返回0, 失敗返回-1.
(3) struct timeval有兩個成員,一個是秒,一個是微妙.
- struct timeval
- {
- long tv_sec; /* seconds */
- long tv_usec; /* microseconds */
- };
由int gettimeofday(struct timeval *tv, struct timezone *tz);擷取.struct timezone結構的定義為:
- struct timezone
- {
- int tz_minuteswest; /* 和Greewich時間差了多少分鐘*/
- int tz_dsttime; /* 日光節約時間的狀態 */
- };
(4) struct timespec有兩個成員,一個是秒,一個是納秒, 所以最高精確度是納秒.
- struct timespec
- {
- time_t tv_sec; /* seconds */
- long tv_nsec; /* nanoseconds */
- };
一般由函數long clock_gettime (clockid_t which_clock, struct timespec *tp); 擷取.擷取特定時鐘的時間,時間通過tp結構傳回,目前定義了6種時鐘,分別是
CLOCK_REALTIME 統目前時間,從1970年1.1日算起
CLOCK_MONOTONIC 系統的啟動時間,不能被設定
CLOCK_PROCESS_CPUTIME_ID 進程已耗用時間
CLOCK_THREAD_CPUTIME_ID 線程已耗用時間
CLOCK_REALTIME_HR CLOCK_REALTIME的高精度版本
CLOCK_MONOTONIC_HR CLOCK_MONOTONIC的高精度版本
擷取特定時鐘的時間精度:
long clock_getres(clockid_t );
設定特定時鐘的時間:
long clock_settime(clockid_t ,struct timespec*);
休眠time中指定的時間,如果遇到訊號中斷而提前返回,則由left_time返回剩餘的時間:
long clock_nanosleep(clockid_t ,int flag,timespec* time,timespec* left_time);
(5) clock_t類型, 由clock_t clock(); 返回擷取.
表示進程佔用的cpu時間. 精確到微秒.
(6)struct tm是直觀意義上的時間表示方法:
- struct tm
- {
- int tm_sec; /* seconds */
- int tm_min; /* minutes */
- int tm_hour; /* hours */
- int tm_mday; /* day of the month */
- int tm_mon; /* month */
- int tm_year; /* year */
- int tm_wday; /* day of the week */
- int tm_yday; /* day in the year */
- int tm_isdst; /* daylight saving time */
- };
struct tm* gmtime(const time_t *timep);struct tm* localtime(const time_t *timep);time_t mktime(struct tm *tm);gmtime和localtime的參數以及傳回值類型相同,區別是前者返回的格林威治標準時間,後者是當地時間.注意: 這邊三個函數都是線程不安全的, 要使用安全執行緒的版本, 需要使用帶_r的版本 -- gmtime_r, localtime_r, mktime_r.
二、 延遲函數主要的延遲函數有:sleep(),usleep(),nanosleep(),select(),pselect().
- unsigned int sleep(unsigned int seconds);
- void usleep(unsigned long usec);
- int nanosleep(const struct timespec *req, struct timespec *rem);
- int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,struct timeval *timeout);
- int pselect(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timespec *timeout, const sigset_t *sigmask);
alarm函數是訊號方式的延遲,這種方式不直觀,這裡不說了。
僅通過函數原型中時間參數類型,可以猜測sleep可以精確到秒級,usleep/select可以精確到微妙級,nanosleep和pselect可以精確到納秒級。
而實際實現中,linux上的nanosleep和alarm相同,都是基於核心時鐘機制實現,受linux核心時鐘實現的影響,並不能達到納秒級的精度,man nanosleep也可以看到這個說明,man裡給出的精度是:Linux/i386上是10 ms ,Linux/Alpha上是1ms。