【问题标题】:Will getting the current date/time be thread-safe in C++20?在 C++20 中获取当前日期/时间是否是线程安全的?
【发布时间】:2018-06-14 20:01:32
【问题描述】:

小问题

直到并包括 C++17,C++ 都没有提供线程安全的方法来获取当前时间或日期。这会在 C++20 中修复吗?

长问题

获取当前时间和日期的唯一可移植方法是使用 std::gmtime 或 std::localtime 函数。 C 早期的残余,这些函数将自实现定义的纪元以来的给定时间转换为日历时间(例如,1515153600 转换为 2018 年 1 月 5 日星期五 12:00:00 GMT)。然而,唯一的缺点是这些函数返回一个指向内部静态变量的指针并且不是线程安全的。更糟糕的是,这个静态变量可能被所有相关函数共享,例如 std::gmtime、std::localtime 和 std::ctime,并且可能在每次调用这些函数时被覆盖。因此,如果您正在使用线程并希望定期检查您面临数据竞争和未定义行为的风险。

显然当前的标准在这方面被打破了。 C++ 标准委员会是否有任何努力来解决这种情况?这有多大可能被包含在 C++20 中?

【问题讨论】:

  • 关于chrono解决方案,霍华德的<date>提案进展顺利。
  • 我不明白添加线程安全时间函数将如何解决您的问题“但是现在您必须确保代码的每一位都实际通过互斥体包装器。如果没有”你可能会再次遇到数据竞争,从而导致未定义的行为。如果你在编码工作分成团队的大型项目中编码,你必须不断提醒每个人他们不应该(!)使用 C++ 标准提供的功能,但请改用您自己的包装器(或冒未定义行为的风险)。”您仍然必须告诉人们不要使用非线程安全函数。
  • @NicolBolas 是的。我的观点是,当这是固定的编码人员可以使用 C++ 标准提供的线程安全函数,并且在线程环境中没有理由不这样做。当然,他们仍然可以朝自己的脚开枪,但现在他们有一个标准提供的选项来朝自己的脚开枪。让 C++ 标准提供这些函数还有一个额外的好处,那就是它可以在内部实现而无需任何锁。
  • #2 是我的提议的目标:open-std.org/jtc1/sc22/wg21/docs/papers/2017/…
  • 在我写这篇文章时,有 3 票接近。如果关闭,我在此承诺投票重新开放。如果其他人愿意,我鼓励他们发表同样的评论。

标签: c++ date datetime time c++20


【解决方案1】:

Howard Hinnant 的 date library C++20 的未来。它是通过p0355r4 提出的,并于 2017 年 11 月批准用于 C++20。它是线程安全的吗?不幸的是,文档和提案似乎都不清楚这一点。但是,像get_tzdb_list 这样的某些函数被明确表示具有“线程安全”。您最好的选择是在 gitter 聊天中询问 Hinnant 本人。然而,Why is there no C++11 threadsafe alternative to std::localtime and std::gmtime? 中的讨论似乎表明它是线程安全的(尽管它从未明确说过)。作为 Nicol Bolas points out,您可以将其包装在互斥体后面。

如果没有,您可以再次获得数据竞争,从而导致未定义的行为。如果您在编码工作被分成多个团队的大型项目中进行编码,您必须不断提醒每个人他们不应该(!)使用 C++ 标准提供的函数,而是使用您自己的包装器(或冒未定义行为的风险) .

在浅层次上,这就是代码审查的目的。 Facebook 对初级开发人员有这个问题,他们一遍又一遍地制造相同的错误。如果您的团队有“奇怪地反复出现的错误”,您需要以某种方式解决它(例如向 linter 添加检查:想到 Clang)。

在更直接的层面上,Google 是这方面的缩影。他们遇到的问题是使用 string 的旧 COW 实现并切换到基于 SSO 的 string。但是,由于他们依赖于使用基于 COW 的 string 的第三方库,因此他们需要在其代码库中同时支持这两者。告诉开发人员使用 Google 包装器是徒劳的。开发人员提出的解决方案是使用带有inline namespaces 的hack。有点极端,但如果您正在处理类似的大型代码库,它可以解决问题。

【讨论】:

  • 注意:即使它不是线程安全的,它也巧妙地解决了 Lomos 在chonro 时钟方面的问题,因为日期/时间与纪元/平台无关。因此,如果它不是线程安全的,您可以将其包装在互斥体后面。
  • 嗨! (波浪 :-) ) 。 Howard Hinnant 的日期库和随后的 C++ 标准化提案是线程安全的! 100% 除了明确记录为非线程安全的小角落情况。这些极端情况涉及在应用程序仍在运行时在运行时更新 TZ 数据库(如果您的应用程序需要一次保持运行数月并需要更新的时区数据库)。在后一种情况下,程序员可以使用一些工具以线程安全的方式遍历此更新,但它并不是开箱即用的安全。 RTFM。
  • 我赞成这个答案,因为它几乎说明了我会说的话。我说的都不是官方的。是的,我参加了委员会。但是不,我没有委员会的正式发言权。没有人这样做,除了 Herb 发布的官方公告(而且并非他的所有通信都是官方公告)。但是感谢您的信任投票。 :-)
  • 一个 nit - Howard 的库已被提议用于 C++20,但尚未被采用。如果它没有被采用,我会感到惊讶,但还没有。
  • 更新:上周,Howard 的提案(基于他的库)被 C++2a(可能是 c++20)接受。
猜你喜欢
  • 1970-01-01
  • 2011-10-18
  • 2020-01-09
  • 2021-09-26
  • 2015-03-22
  • 2019-03-05
  • 2011-03-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多