在C ++ 20中获取当前日期/时间是否是线程安全的? [英] Will getting the current date/time be thread-safe in C++20?

查看:180
本文介绍了在C ++ 20中获取当前日期/时间是否是线程安全的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

简短问题

直到C ++ 17(包括C ++ 17),C ++都不提供获取当前时间或日期的线程安全方法。这会在C ++ 20中解决吗?

Up to and including C++17, C++ provides no thread-safe way to get the current time or date. Will this be fixed in C++20?

常见问题

获取当前时间和日期的唯一可移植方法是使用std :: gmtime或std :: localtime函数。从C的早期开始,这些函数会将自实现定义的纪元以来的给定时间转换为日历时间(例如,将1515153600转换为星期五,2018年1月5日格林尼治标准时间12:00:00 GMT)。但是,唯一的缺点是这些函数返回指向内部静态变量的指针,并且不是线程安全的。更糟糕的是,所有相关功能(例如std :: gmtime,std :: localtime和std :: ctime)都可能共享此静态变量,并且每次调用这些函数时,它们都会被覆盖。因此,如果您使用线程并希望定期检查时间,则可能会冒数据竞争和不确定的行为的风险。

The only portable way to get the current time and date is by using the std::gmtime or std::localtime functions. Remnants from the early days of C, these functions convert a given time since an implementation-defined epoch into calender time (for example, 1515153600 into Fri, 05 Jan 2018 12:00:00 GMT). The only downside, however, is that those functions return a pointer to an internal static variable and aren't threadsafe. What's even worse is that this static variable may be shared by all related functions such as std::gmtime, std::localtime, and std::ctime and may be overwritten on each invocation of any of those functions. So if you're using threads and want to regularly check the time you risk data races and undefined behavior.

很显然,当前的标准在这方面已被违反。 C ++标准委员会是否有任何努力来解决这种情况,以及C ++ 20中将包含这种可能性吗?

推荐答案

Howard Hinnant的日期库 ++ 20。它是通过 p0355r4 提出并获得批准的在2017年11月推出C ++ 20。线程安全吗?不幸的是,文档和建议似乎都不清楚。但是,某些函数如 get_tzdb_list 被明确表示具有线程安全性。最好的选择是在 gitter 聊天。但是,为什么中的讨论为什么建议没有std :: localtime和std :: gmtime的C ++ 11线程安全替代品?它是线程安全的(即使从未明确指出)。正如Nicol Bolas 指出

Howard Hinnant's date library is what's coming for C++20. It was proposed via p0355r4 and approved for C++20 in Nov. 2017. Is it thread safe? Unfortunately, neither the documentation nor proposal seem to be clear on this. However, certain functions like get_tzdb_list are explicitly said to have "Thread Safety". Your best option is to ask Hinnant himself in the gitter chat. However, discussion in Why is there no C++11 threadsafe alternative to std::localtime and std::gmtime? seems to suggest that it is thread-safe (even though it's never explicitly said). As Nicol Bolas points out you can just wrap it behind a mutex.


如果没有,则可以再次发生数据争用,从而导致不确定的行为。如果您要在将编码工作分为多个团队的大型项目中进行编码,则必须不断提醒每个人,他们不应该(!)使用C ++标准提供的功能,而应使用自己的包装器(否则可能会有不确定的行为)

If it doesn't you can again get data races and hence undefined behavior. If you're coding on large projects where coding work is divided into teams, you have to continously remind everyone that they should not (!) use the functions provided by the C++ standard, but use your own wrapper instead (or risk undefined behavior).

从浅层次上讲,这就是代码审查的目的。 Facebook 对于初级开发人员会不断出现相同错误的问题。如果您的团队存在好奇地重复出现的bug,则需要以某种方式解决(例如,在linter中添加检查:想到Clang)。

At a shallow level, this is what code reviews are for. Facebook has this problem for junior developers where they keep making the same bugs over and over. If your team has "curiously recurring bugs", you need to address it somehow (like adding checks to linter: Clang comes to mind).

直接得多, Google 是其缩影。他们遇到的问题是使用旧的COW实施 string 并切换到基于SSO的 string 。但是,由于他们依赖使用基于COW的 string 的第三方库,因此他们需要在代码库中同时支持这两种库。告诉开发人员使用Google包装器是徒劳的。开发人员想出的解决方案是使用带有内联名称空间的黑客。有点极端,但是如果您要处理类似的大型代码库,则可以解决问题。

At a much more direct level, Google is the epitome of this. The problem they were having was using the old COW implementation of string and switching over to SSO-based string. However, because they relied on third party libraries that used COW-based string, they needed to support both in their codebase. Telling developers to use the Google wrapper was a futile effort. The solution the developer came up with was using a hack with inline namespaces. A bit extreme, but if you are dealing with a similarly large codebase, it could do the trick.

这篇关于在C ++ 20中获取当前日期/时间是否是线程安全的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆