[英]<time.h> Shared Internal Object - struct tm
我一直在研究C時間庫的例程,因為我需要一種跟蹤程序日志文件中時間的方法。 我發現執行此操作的方法是擁有一個time_t
對象,該對象僅保留自1970年1月1日UTC 00:00以來的秒數。 然后,我將此time_t
對象解析為localtime(time_t* argument)
例程,該例程將返回指向tm
結構的指針。 從1970年1月1日開始,后者將以更復雜的結構保存時間,將以秒為單位的時間轉換為年,月,日,小時等。從1970年1月1日開始,此tm
結構指針最終可以由asctime(strcut tm* argument)
返回人類友好的日志記錄時間(即2016年9月7日星期三13:45:23)。
我的問題是關於struct tm
對象。 正如我們在Cplusplus的示例代碼中看到的那樣,從不聲明struct tm
對象,而僅聲明了一個指針。 意味着此對象在其他地方聲明,我們正在訪問它。 參考鏈接本身指出:
"The function also accesses and modifies a shared internal object,
which may introduce data races on concurrent calls to gmtime and
localtime. Some libraries provide an alternative function that avoids
this data race: localtime_r (non-portable)."
那么,誰創建了struct tm
對象? 第一次加載時是C時間庫嗎? 那是否意味着加載該庫的第一個進程將聲明該對象,而所有其他進程將僅與已聲明的對象共享該庫? 為了避免這些Data Races問題,只為每個調用創建一個新的struct tm
對象並返回一個指向它的指針,以便每個程序都有自己的結構,這會更好嗎?
也許有一個struct tm MyProgramStruct; localtime(&Rawtime, &MyProgramStruct);
struct tm MyProgramStruct; localtime(&Rawtime, &MyProgramStruct);
而不是每個使用Ctime的程序都使用單個結構? 這樣做有任何原因嗎?
最后,由於可能由於程序不同步而導致錯誤輸出,因此使用C時間庫localtime
時間例程是否是一種不好的做法?
鏈接中的示例代碼:
/* localtime example */
#include <stdio.h> /* puts, printf */
#include <time.h> /* time_t, struct tm, time, localtime */
int main ()
{
time_t rawtime;
struct tm * timeinfo;
time (&rawtime);
timeinfo = localtime (&rawtime);
printf ("Current local time and date: %s", asctime(timeinfo));
return 0;
}
那么,誰創建了struct tm對象? 第一次加載時是C時間庫嗎?
根據localtime()
函數的文檔,它返回一個指向靜態分配的結構的指針。 該結構屬於C庫; 該函數提供了指向它的指針。 確切的位置以及確切的存儲時間和分配方式的詳細信息無關緊要,並且可能因實現而異。 您只需要了解同一進程的不同調用可以一起使用並提供指向同一結構的指針。
那是否意味着加載該庫的第一個進程將聲明該對象,而所有其他進程將僅與已聲明的對象共享該庫?
不需要。您不必擔心結構在進程之間共享,而只需要擔心跨多個調用以及同一進程中的多個線程之間共享該結構。
為了避免這些Data Races問題,只為每個調用創建一個新的struct tm對象並返回一個指向它的指針,以便每個程序都有自己的結構,這會更好嗎? 也許有一個
struct tm MyProgramStruct; localtime(&Rawtime, &MyProgramStruct);
struct tm MyProgramStruct; localtime(&Rawtime, &MyProgramStruct);
而不是每個使用Ctime的程序都使用單個結構? 這樣做有任何原因嗎?
同樣,這不是跨進程問題,而只是一個進程內問題,這仍然很糟糕。 是的,可以通過不共享該結構來解決該問題,這就是區分函數localtime_r()
地方。 但是現有功能不能更改為相同功能,因為這將對用戶釋放新提供的結構提出新要求。
localtime()
的設計者希望使其易於使用,的確如此,只要您不擔心共享數據問題。 如果您的程序是單線程的,則可以很容易地避免使用它。 localtime()
並非唯一具有此類問題的標准庫函數。
最后,由於可能由於程序不同步而導致錯誤輸出,因此使用C時間庫
localtime
時間例程是否是一種不好的做法?
不是因為這個原因,不是,因為沒有跨進程問題。 在使用localtime()
和其他具有類似靜態存儲的函數時,您確實需要注意,例如strtok()
。 但是您可以根據程序逐個判斷是否存在任何數據爭用-您無需擔心未指定的其他程序的干擾。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.