1. 程式人生 > >linux系統中的時間API和函式庫

linux系統中的時間API和函式庫

linux系統中的時間函式 ---jiffies的引入 jiffies是linux核心中的一個全域性變數,這個變數用來記錄以核心的節拍時間為單位時間長度的一個數值。 linux系統如何記錄時間 (1)核心在開機啟動的時候會讀取RTC硬體獲取一個時間作為初始基準時間,這個基準時間對應一個jiffies值(這個基準時間換算成jiffies值的方法是:用這個時間減去1970-01-01 00:00:00 +0000(UTC),然後把這個時間段換算成jiffies數值),這個jiffies值作為我們開機時的基準jiffies值存在。然後系統執行時每個時鐘節拍的末尾都會給jiffies這個全域性變數加1,因此作業系統就使用jiffies這個全域性變數記錄了下來當前的時間。當我們需要當前時間點時,就用jiffies這個時間點去計算(計算方法就是先把這個jiffies值對應的時間段算出來,然後加上1970-01-01 00:00:00 +0000(UTC)即可得到這個時間點) (2)其實作業系統只在開機時讀一次RTC,整個系統執行過程中RTC是無作用的。RTC的真正作用其實是在OS的2次開機之間進行時間的儲存。 (3)理解時一定要點時間和段時間結合起來理解。jiffies這個變數記錄的其實是段時間(其實就是當前時間和1970-01-01 00:00:00 +0000(UTC)這個時間的差值) (4)一個時間節拍的時間取決於作業系統的配置,現代linux系統一般是10ms或者1ms。這個時間其實就是排程時間,在核心中用HZ來記錄和表示。如果HZ定義成1000難麼時鐘節拍就是1/HZ,也就是1ms。 linux中時間相關的系統呼叫 (1)常用的時間相關的API和C庫函式有9個:time/ctime/localtime/gmtime/mktime/asctime/strftime/gettimeofday/settimeofday有9個:time/ctime/localtime/gmtime/mktime/asctime/strftime/gettimeofday/settimeofday (2)gmtime和localtime會把time得到的秒數變成一個struct tm結構體表示的時間。區別是gmtime得到的是國際時間,而localtime得到的是本地(指的是你執行localtime函式的程式所在的計算機所設定的時區對應的本地時間)時間。mktime用來完成相反方向的轉換(struct tm到time_t) (3)如果從struct tm出發想得到字串格式的時間,可以用asctime或者strftime都可以。(如果從time_t出發想得到字串格式的時間用ctime即可) (4)gettimeofday返回的時間是由struct timeval和struct timezone這兩個結構體來共同表示的,其中timeval表示時間,而timezone表示時區。settimeofday是用來設定當前的時間和時區的。 (5)總結:不管用哪個系統呼叫,最終得到的時間本質上都是一個時間(這個時間最終都是從kernel中記錄的jiffies中計算得來的),只不過不同的函式返回的時間的格式不同,精度不同。 1、time
(1)time能得到一個當前時間距離標準起點時間1970-01-01 00:00:00 +0000(UTC)過去了多少秒

2、ctime
(1)ctime可以從time_t出發得到一個容易觀察的字串格式的當前時間。
(2)ctime好處是很簡單好用,可以直接得到當前時間的字串格式,直接列印來看。壞處是ctime的列印時間格式是固定的,沒法按照我們的想法去變。
(3)實驗結果可以看出ctime函式得到的時間是考慮了計算機中的本地時間的(計算機中的時區設定)

3、gmtime和localtime
(1)gmtime獲取的時間中:年份是以1970為基準的差值,月份是0表示1月,小時數是以UTC時間的0時區為標準的小時數(北京是東8區,因此北京時間比這個時間大8)
(2)猜測localtime和gmtime的唯一區別就是localtime以當前計算機中設定的時區為小時的時間基準,其餘一樣。實踐證明我們的猜測是正確的。

  time_t tNow = -1;
	struct tm tmNow;
	
	// time
	//tNow = time(NULL);		// 返回值
	time(&tNow);				// 指標做輸出型引數
	printf("time: %ld.\n", tNow);
	
	// ctime
	printf("ctime: %s.\n", ctime(&tNow));
	
	// gmtime 和localtime
	memset(&tmNow, 0, sizeof(tmNow));
	gmtime_r(&tNow, &tmNow);
	printf("年%d月%d日%d時%d.\n", tmNow.tm_year, tmNow.tm_mon, tmNow.tm_mday, tmNow.tm_hour);
	
	memset(&tmNow, 0, sizeof(tmNow));
	localtime_r(&tNow, &tmNow);
	printf("年%d月%d日%d時%d.\n", tmNow.tm_year, tmNow.tm_mon, tmNow.tm_mday, tmNow.tm_hour);

4、mktime
(1)從OS中讀取時間時用不到mktime的,這個mktime是用來向作業系統設定時間時用的。

5、asctime
(1)asctime得到一個固定格式的字串格式的當前時間,效果上和ctime一樣的。區別是ctime從time_t出發,而asctime從struct tm出發。

6、strftime
(1)asctime和ctime得到的時間字串都是固定格式的,沒法使用者自定義格式
(2)如果需要使用者自定義時間的格式,則需要用strftime。

7、gettimeofday和settimeofday
(1)前面講到的基於time函式的那個系列都是以秒為單位來獲取時間的,沒有比秒更精確的時間。
(2)有時候我們程式希望得到非常精確的時間(譬如以us為單位),這時候就只能通過gettimeofday來實現了。

char buf[100];
	struct timeval tv = {0};
	struct timezone tz = {0};
#if 0
	// asctime
	memset(&tmNow, 0, sizeof(tmNow));
	localtime_r(&tNow, &tmNow);
	printf("年%d月%d日%d時%d.\n", tmNow.tm_year, tmNow.tm_mon, tmNow.tm_mday, tmNow.tm_hour);
	printf("asctime:%s.\n", asctime(&tmNow));
#endif

#if 0
	// strftime
	memset(&tmNow, 0, sizeof(tmNow));
	localtime_r(&tNow, &tmNow);
	printf("年%d月%d日%d時%d.\n", tmNow.tm_year, tmNow.tm_mon, tmNow.tm_mday, tmNow.tm_hour);
	
	memset(buf, 0, sizeof(buf));
	strftime(buf, sizeof(buf), "%Y * %m * %d, %H-%M-%S.", &tmNow);
	printf("時間為:[%s].\n", buf);
#endif

	// gettimeofday
	ret = gettimeofday(&tv, &tz);
	if (ret < 0)
	{
		perror("gettimeofday");
		return -1;
	}
	printf("seconde: %ld.\n", tv.tv_sec);
	printf("timezone:%d.\n", tz.tz_minuteswest);