草庐IT

c++ - 获取当前日期/时间在 C++20 中是线程安全的吗?

coder 2023-11-13 原文

小问题

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

长问题

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

显然,当前的标准在这方面已被打破。 C++ 标准委员会是否采取了任何措施来解决这种情况,以及将其包含在 C++20 中的可能性有多大?

最佳答案

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?似乎暗示它是线程安全的(即使它从未明确说过)。作为尼可波拉斯 points out您可以将它包装在互斥锁后面。

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对于初级开发人员来说有这个问题,他们一遍又一遍地犯同样的错误。如果您的团队有“奇怪的反复出现的错误”,您需要以某种方式解决它(比如向 linter 添加检查:想到 Clang)。

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

C++20获取当前时间的线程安全代码

#include <chrono>
#include <format>
#include <iostream>

int
main()
{
    using namespace std;
    using namespace std::chrono;

    auto now = system_clock::now();
    cout << format("{:%F %T %Z}", now) << '\n';
    cout << format("{:%F %T %Z}", zoned_time{current_zone(), now}) << '\n';
    cout << format("{:%F %T %Z}", zoned_time{"Australia/Sydney", now}) << '\n';
}

示例输出:

2022-06-09 01:14:31.844518 UTC
2022-06-08 21:14:31.844518 EDT
2022-06-09 11:14:31.844518 AEST

此示例使用 system_clock 获取 UTC 的当前时间,显示该时间,然后将该时间转换为我的计算机当前的本地时区和澳大利亚悉尼的当前时间。

所有这些都是线程安全的。您可以在多个线程中执行完全相同的代码,并且不会出现竞争条件。

免责声明:在我撰写本文时,并非所有平台都实现了 C++20 的这一部分。有关详细信息,请参阅您的 std::lib 的 C++20 状态页面。

关于c++ - 获取当前日期/时间在 C++20 中是线程安全的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48106291/

有关c++ - 获取当前日期/时间在 C++20 中是线程安全的吗?的更多相关文章

  1. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  2. ruby - 如何使用 Ruby aws/s3 Gem 生成安全 URL 以从 s3 下载文件 - 2

    我正在编写一个小脚本来定位aws存储桶中的特定文件,并创建一个临时验证的url以发送给同事。(理想情况下,这将创建类似于在控制台上右键单击存储桶中的文件并复制链接地址的结果)。我研究过回形针,它似乎不符合这个标准,但我可能只是不知道它的全部功能。我尝试了以下方法:defauthenticated_url(file_name,bucket)AWS::S3::S3Object.url_for(file_name,bucket,:secure=>true,:expires=>20*60)end产生这种类型的结果:...-1.amazonaws.com/file_path/file.zip.A

  3. ruby-on-rails - date_field_tag,如何设置默认日期? [ rails 上的 ruby ] - 2

    我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问

  4. ruby-on-rails - Ruby 检查日期时间是否为 iso8601 并保存 - 2

    我需要检查DateTime是否采用有效的ISO8601格式。喜欢:#iso8601?我检查了ruby​​是否有特定方法,但没有找到。目前我正在使用date.iso8601==date来检查这个。有什么好的方法吗?编辑解释我的环境,并改变问题的范围。因此,我的项目将使用jsapiFullCalendar,这就是我需要iso8601字符串格式的原因。我想知道更好或正确的方法是什么,以正确的格式将日期保存在数据库中,或者让ActiveRecord完成它们的工作并在我需要时间信息时对其进行操作。 最佳答案 我不太明白你的问题。我假设您想检查

  5. ruby - 简单获取法拉第超时 - 2

    有没有办法在这个简单的get方法中添加超时选项?我正在使用法拉第3.3。Faraday.get(url)四处寻找,我只能先发起连接后应用超时选项,然后应用超时选项。或者有什么简单的方法?这就是我现在正在做的:conn=Faraday.newresponse=conn.getdo|req|req.urlurlreq.options.timeout=2#2secondsend 最佳答案 试试这个:conn=Faraday.newdo|conn|conn.options.timeout=20endresponse=conn.get(url

  6. ruby - 检查日期是否在过去 7 天内 - 2

    我的日期格式如下:"%d-%m-%Y"(例如,今天的日期为07-09-2015),我想看看是不是在过去的七天内。谁能推荐一种方法? 最佳答案 你可以这样做:require"date"Date.today-7 关于ruby-检查日期是否在过去7天内,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/32438063/

  7. ruby - 从 Ruby 中的主机名获取 IP 地址 - 2

    我有一个存储主机名的Ruby数组server_names。如果我打印出来,它看起来像这样:["hostname.abc.com","hostname2.abc.com","hostname3.abc.com"]相当标准。我想要做的是获取这些服务器的IP(可能将它们存储在另一个变量中)。看起来IPSocket类可以做到这一点,但我不确定如何使用IPSocket类遍历它。如果它只是尝试像这样打印出IP:server_names.eachdo|name|IPSocket::getaddress(name)pnameend它提示我没有提供服务器名称。这是语法问题还是我没有正确使用类?输出:ge

  8. ruby - 获取模块中定义的所有常量的值 - 2

    我想获取模块中定义的所有常量的值:moduleLettersA='apple'.freezeB='boy'.freezeendconstants给了我常量的名字:Letters.constants(false)#=>[:A,:B]如何获取它们的值的数组,即["apple","boy"]? 最佳答案 为了做到这一点,请使用mapLetters.constants(false).map&Letters.method(:const_get)这将返回["a","b"]第二种方式:Letters.constants(false).map{|c

  9. ruby-on-rails - 将 Ruby 中的日期/时间格式化为 YYYY-MM-DD HH :MM:SS - 2

    这个问题在这里已经有了答案:Railsformattingdate(4个答案)关闭4年前。我想格式化Time.Now函数以显示YYYY-MM-DDHH:MM:SS而不是:“2018-03-0909:47:19+0000”该函数需要放在时间中.现在功能。require‘roo’require‘roo-xls’require‘byebug’file_name=ARGV.first||“Template.xlsx”excel_file=Roo::Spreadsheet.open(“./#{file_name}“,extension::xlsx)xml=Nokogiri::XML::Build

  10. ruby - 查找字符串中的内容类型(数字、日期、时间、字符串等) - 2

    我正在尝试解析一个CSV文件并使用SQL命令自动为其创建一个表。CSV中的第一行给出了列标题。但我需要推断每个列的类型。Ruby中是否有任何函数可以找到每个字段中内容的类型。例如,CSV行:"12012","Test","1233.22","12:21:22","10/10/2009"应该产生像这样的类型['integer','string','float','time','date']谢谢! 最佳答案 require'time'defto_something(str)if(num=Integer(str)rescueFloat(s

随机推荐