7

我们有一些代码想要localtime经常从多个线程调用。(相关背景:它是一个服务器,您可以要求它以字符串形式的本地时间,它希望能够每秒处理 100Ks 的请求。)

我们发现,在 Ubuntu Linux 12.04 上,glibc 函数localtime_r(“reentrant localtime”)调用__tz_convert仍然需要全局锁!

(此外, FreeBSD似乎在每次localtime_r调用时都会tzset调用,因为他们偏执于程序可能已经完成了setenv("TZ")和/或用户下载了/etc/localtime从现在到上次localtime_r调用的新版本。(这是相反的这里描述的情况;似乎 glibctzset 每次调用localtimebut notlocaltime_r,只是为了混淆。)

显然,这对性能来说是很糟糕的。出于我们的目的,我们希望在服务器开始运行时基本上“快照”我们当前时区的规则,然后永远使用该快照。所以我们将继续遵守夏令时规则(因为何时切换到 DST 的规则将成为快照的一部分),但我们永远不会回到磁盘、使用互斥锁或做任何其他会导致线程的事情阻止。(我们可以不尊重 tzinfo 的下载更新,也不尊重对 的更改/etc/localtime;我们不希望服务器在运行时物理更改时区。)

但是,我在网上找不到任何关于如何处理时区规则的信息——是否有用户空间 API 可以使用它们,或者我们是否将被迫重新实现几百行 glibc 代码来自己读取时区数据.

我们是否必须重新实现下游的所有内容__tz_convert——包括tzfile_read,因为它似乎没有暴露给用户?或者是否有一些 POSIX 接口和/或第三方库可用于处理时区规则?

(我看过http://www.iana.org/time-zones/repository/tz-link.html但我不确定它是否有用。)

4

2 回答 2

3

使用https://github.com/google/cctz

它速度很快,应该用一个非常简单的 API 完成你想要的一切。

特别是,对于等效于 的 cctz localtime,请使用该cctz::BreakTime()函数。例如,https://github.com/google/cctz/blob/master/examples/example3.cc

于 2015-11-24T15:09:53.917 回答
1

也许这个免费的开源时区库会满足需要。

它有一个名为的配置标志,在此处LAZY_INIT完整记录。默认情况下它是打开的,并且会在第一次访问每个单独的时区时调用。但是你可以编译:std::call_once

-DLAZY_INIT=0

然后是std::call_once走开的电话。每个时区都从磁盘读取并在首次访问时完全初始化(通过函数本地静态)。从那时起,事情就稳定了,没有锁,没有磁盘访问。自然,这会预先增加初始化时间,但会减少每个时区的“首次访问”时间。

这个库需要 C++11/14,因此可能不适合这个原因。它基于(并大量使用)C++11<chrono>库。这是打印出当前本地时间的示例代码:

#include "tz.h"
#include <iostream>

int
main()
{
    using namespace date;
    auto local = make_zoned(current_zone(), std::chrono::system_clock::now());
    std::cout << local << '\n';
}

这只是为我输出:

2016-04-12 10:13:14.585945 EDT

该库是一种现代的高性能线程安全设计。它也非常灵活且文档齐全。它的功能远远超出了 C 的简单替代localtime。与 C API 不同,您可以指定所需的任何IANA 时区,例如:

    auto local = make_zoned("Europe/London", std::chrono::system_clock::now());

这给出了伦敦的当前时间:

2016-04-12 15:19:59.035533 BST

请注意,默认情况下时间戳的精度是std::chrono::system_clock. 如果您更喜欢另一种精度,这很容易实现:

using namespace date;
using namespace std::chrono;
auto local = make_zoned("Europe/London", std::chrono::system_clock::now());
std::cout << format("%F %H:%M %Z", local) << '\n';

2016-04-12 15:22 BST

有关更多详细信息,请参阅文档

于 2016-04-12T14:24:33.637 回答