简体   繁体   English

<time.h>共享内部对象-struct tm

[英]<time.h> Shared Internal Object - struct tm

I was looking into the routines of the C time library, since I needed a way to keep track of time on the log file of a program. 我一直在研究C时间库的例程,因为我需要一种跟踪程序日志文件中时间的方法。 I found the way to do it was to have a time_t object, which holds nothing more than the number of seconds since 1st Jan 1970 00:00 UTC. 我发现执行此操作的方法是拥有一个time_t对象,该对象仅保留自1970年1月1日UTC 00:00以来的秒数。 Then, I'd parse this time_t object to the localtime(time_t* argument) routine, that would return a pointer to a tm structure. 然后,我将此time_t对象解析为localtime(time_t* argument)例程,该例程将返回指向tm结构的指针。 This latter would hold the time in a more complex structure, translating the time in seconds for years, months, days, hours, etc., since 1st Jan 1970. This tm structure pointer could be finally used by asctime(strcut tm* argument) to return a human friendly time for the log (ie Wed Sep 7 13:45:23 2016). 从1970年1月1日开始,后者将以更复杂的结构保存时间,将以秒为单位的时间转换为年,月,日,小时等。从1970年1月1日开始,此tm结构指针最终可以由asctime(strcut tm* argument)返回人类友好的日志记录时间(即2016年9月7日星期三13:45:23)。

My question is about the struct tm object. 我的问题是关于struct tm对象。 As we can see in the example code from Cplusplus , a struct tm object is never declared, only a pointer. 正如我们在Cplusplus的示例代码中看到的那样,从不声明struct tm对象,而仅声明了一个指针。 Meaning this object is declared somewhere else and we are just accessing it. 意味着此对象在其他地方声明,我们正在访问它。 The reference link itself states: 参考链接本身指出:

"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)."

So, who creates the struct tm object? 那么,谁创建了struct tm对象? Is it the C time library in the first time it is loaded? 第一次加载时是C时间库吗? That would mean that the first process that loads the library would declare the object and all other processes would just share this library with the object already declared? 那是否意味着加载该库的第一个进程将声明该对象,而所有其他进程将仅与已声明的对象共享该库? Wouldn't it be better, in order to avoid those Data Races issues, to just create a new struct tm object for each call and return a pointer to it so each program has its own structure? 为了避免这些Data Races问题,只为每个调用创建一个新的struct tm对象并返回一个指向它的指针,以便每个程序都有自己的结构,这会更好吗?

Maybe having a struct tm MyProgramStruct; localtime(&Rawtime, &MyProgramStruct); 也许有一个struct tm MyProgramStruct; localtime(&Rawtime, &MyProgramStruct); struct tm MyProgramStruct; localtime(&Rawtime, &MyProgramStruct); instead of a single struct for every program using Ctime? 而不是每个使用Ctime的程序都使用单个结构? Any reason it's done this way instead? 这样做有任何原因吗?

Finally, is using C time library localtime routine a bad practice because of the possibility of the unsynchronization of programs leading to a wrong output? 最后,由于可能由于程序不同步而导致错误输出,因此使用C时间库localtime时间例程是否是一种不好的做法?

Example code from the link: 链接中的示例代码:

/* 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;
}

So, who creates the struct tm object? 那么,谁创建了struct tm对象? Is it the C time library in the first time it is loaded? 第一次加载时是C时间库吗?

According to the docs for the localtime() function, it returns a pointer to a statically allocated struct. 根据localtime()函数的文档,它返回一个指向静态分配的结构的指针。 That struct belongs to the C library; 该结构属于C库; the function provides a pointer to it. 该函数提供了指向它的指针。 The fine details of exactly where it lives and exactly when and how storage for it is allocated don't matter and may vary from implementation to implementation. 确切的位置以及确切的存储时间和分配方式的详细信息无关紧要,并且可能因实现而异。 You just have to understand that different calls by the same process work with and provide pointers to the same struct. 您只需要了解同一进程的不同调用可以一起使用并提供指向同一结构的指针。

That would mean that the first process that loads the library would declare the object and all other processes would just share this library with the object already declared? 那是否意味着加载该库的第一个进程将声明该对象,而所有其他进程将仅与已声明的对象共享该库?

No. You do not need to worry about the struct being shared between processes, only about it being shared across multiple calls and between multiple threads in the same process. 不需要。您不必担心结构在进程之间共享,而只需要担心跨多个调用以及同一进程中的多个线程之间共享该结构。

Wouldn't it be better, in order to avoid those Data Races issues, to just create a new struct tm object for each call and return a pointer to it so each program has its own structure? 为了避免这些Data Races问题,只为每个调用创建一个新的struct tm对象并返回一个指向它的指针,以便每个程序都有自己的结构,这会更好吗? Maybe having a struct tm MyProgramStruct; localtime(&Rawtime, &MyProgramStruct); 也许有一个struct tm MyProgramStruct; localtime(&Rawtime, &MyProgramStruct); struct tm MyProgramStruct; localtime(&Rawtime, &MyProgramStruct); instead of a single struct for every program using Ctime? 而不是每个使用Ctime的程序都使用单个结构? Any reason it's done this way instead? 这样做有任何原因吗?

Again, it's not a cross-process problem, only an intra-process problem, which is still bad enough. 同样,这不是跨进程问题,而只是一个进程内问题,这仍然很糟糕。 Yes, that problem would be addressed by not sharing the struct, and that's what distinguishes the function localtime_r() , where it is available. 是的,可以通过不共享该结构来解决该问题,这就是区分函数localtime_r()地方。 But the existing function cannot be changed to do the same, because that would introduce a new requirement on users to free the provided struct. 但是现有功能不能更改为相同功能,因为这将对用户释放新提供的结构提出新要求。

The designers of localtime() wanted to make it easy to use, and indeed it is, as long as you don't run afoul of the shared data issue. localtime()的设计者希望使其易于使用,的确如此,只要您不担心共享数据问题。 If your program is single-threaded, then you can avoid it fairly easily. 如果您的程序是单线程的,则可以很容易地避免使用它。 localtime() is not the only standard library function with an issue of this sort. localtime()并非唯一具有此类问题的标准库函数。

Finally, is using C time library localtime routine a bad practice because of the possibility of the unsynchronization of programs leading to a wrong output? 最后,由于可能由于程序不同步而导致错误输出,因此使用C时间库localtime时间例程是否是一种不好的做法?

Not for that reason, no, because there is no cross-process problem. 不是因为这个原因,不是,因为没有跨进程问题。 You do need to pay attention when using localtime() and other functions with similar static storage, such as strtok() . 在使用localtime()和其他具有类似静态存储的函数时,您确实需要注意,例如strtok() But you can judge on a program by program basis whether there is any data race -- you do not need to worry about interference from unspecified other programs. 但是您可以根据程序逐个判断是否存在任何数据争用-您无需担心未指定的其他程序的干扰。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM