如何保证程序启动时存在一个std::chrono::tzdb?

问题描述 投票:0回答:1

有没有办法确定时区数据库是否在程序启动时初始化?

我的目标是不因为不存在

tzdb
而导致 std::runtime_error 在程序中抛出。我需要保证时区数据库在程序的生命周期内存在。

一个原始的例子:

#include <iostream>
#include <chrono>
#include <stdexcept>


int main( )
{
    try
    {
        std::cout << std::chrono::get_tzdb_list().front().current_zone()->name() << '\n';
    }
    catch ( const std::runtime_error& re )
    {
        std::cout << re.what( ) << '\n';
        return 1;
    }

// rest of the program that happily references the `std::chrono::time_zone` objects in
// the database with no errors
}

如果我没记错的话,程序中第一次调用

std::chrono::get_tzdb_list()
会尝试初始化数据库,如果不成功就会抛出异常。

但显然,上述方法并不理想,因为我不想打印当前区域的名称。如何在不打印任何内容的情况下实现这一点,并且仍然确保编译器不会优化对

std::chrono::get_tzdb_list()
的调用?

c++ error-handling timezone c++20 c++-chrono
1个回答
0
投票

只要

get_tzdb()
就足够了。我喜欢将它放在一个独立的线程中,以便它可以与其他初始化作业同时发生:

#include <chrono>
#include <iostream>
#include <thread>

int
main()
{
    std::thread{
        []()
        {
            try
            {
                (void)std::chrono::get_tzdb();
            }
            catch (std::exception const& e)
            {
                std::cout << e.what() << '\n';
                throw;
            }
        }
    }.detach();
    // ...
}

访问是线程安全的。如果程序的主要部分尝试在此

tzdb
之前访问
thread
,其中一个将首先到达那里,另一个将阻塞,直到第一次访问完成。

© www.soinside.com 2019 - 2024. All rights reserved.