首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 ><time.h>共享内部对象- struct

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

Stack Overflow用户
提问于 2016-09-09 13:11:20
回答 1查看 536关注 0票数 3

我正在查看C时间库的例程,因为我需要一种方法来跟踪程序日志文件上的时间。我找到了这样做的方法,就是有一个time_t对象,它只保存自1970年1月1日00:00UTC以来的秒数。然后,我将这个time_t对象解析为localtime(time_t* argument)例程,这将返回指向tm结构的指针。从1970年1月1日起,后者将把时间保存在一个更复杂的结构中,以秒为单位,从1970年1月1日开始,将时间转换为数年、几个月、几天、几小时。这个tm结构指针最终可以被asctime(strcut tm* argument)用来返回日志的人类友好性时间(即Wed 9月7日13:45:23 2016)。

我的问题是关于struct tm对象。正如我们在Cplusplus中的示例代码中所看到的那样,struct tm对象从未被声明过,只有一个指针。这意味着这个对象是在其他地方声明的,我们只是在访问它。参考链接本身指出:

代码语言:javascript
复制
"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时间库吗?这意味着加载库的第一个进程将声明对象,而所有其他进程将只与已经声明的对象共享这个库?为了避免这些数据竞争问题,只为每个调用创建一个新的struct tm对象,并返回一个指向它的指针,这样每个程序都有自己的结构,这不是更好吗?

也许每个使用Ctime的程序都有一个struct tm MyProgramStruct; localtime(&Rawtime, &MyProgramStruct);而不是一个单独的结构?有什么理由这样做吗?

最后,由于程序的不同步可能导致错误的输出,所以使用C时间库localtime例程是一种不好的做法吗?

链接中的示例代码:

代码语言:javascript
复制
/* 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;
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-09-09 13:35:49

那么,是谁创建了struct对象?第一次加载时是C时间库吗?

根据localtime()函数的文档,它返回一个指向静态分配的结构的指针。该结构属于C库;该函数提供了指向它的指针。它的确切位置、何时以及如何分配其存储空间的详细细节并不重要,而且可能因实现而异。您只需了解,同一进程的不同调用与同一个结构一起工作,并提供指向相同结构的指针。

这意味着加载库的第一个进程将声明对象,而所有其他进程将只与已经声明的对象共享这个库?

不是的。您不需要担心进程之间共享的结构,只需要担心它在多个调用之间以及在同一个进程中的多个线程之间共享。

为了避免这些数据竞争问题,是否应该为每个调用创建一个新的struct对象,并返回一个指向它的指针,以便每个程序都有自己的结构?也许每个使用Ctime的程序都有一个struct tm MyProgramStruct; localtime(&Rawtime, &MyProgramStruct);而不是一个单独的结构?有什么理由这样做吗?

再说一遍,这不是一个跨进程的问题,只是一个进程内的问题,这个问题仍然够糟糕的。是的,这个问题可以通过不共享结构来解决,这就是函数localtime_r()的区别所在,因为它是可用的。但是,现有的函数不能更改为同样的操作,因为这将引入一个新的要求,要求用户释放提供的结构。

localtime()的设计人员希望使其易于使用,事实上,只要您不与共享数据问题发生冲突,就可以使用它。如果您的程序是单线程的,那么您可以相当容易地避免它.localtime()不是唯一存在这类问题的标准库函数。

最后,由于程序的不同步可能导致错误的输出,所以使用C时间库localtime例程是一种不好的做法吗?

不是因为这个原因,不是,因为没有跨进程的问题。在使用localtime()和具有类似静态存储的其他函数(如strtok() )时,您确实需要注意。但是你可以根据程序来判断是否有任何数据竞争--你不需要担心来自未指定的其他程序的干扰。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39412385

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档