【发布时间】:2019-08-27 10:05:28
【问题描述】:
我创建了两个函数来计算给定纪元时间戳的当天开始时间戳(即当天 00:00:00)和小时(从 1 到 24)。
#include <cstdint>
#include <ctime>
const uint8_t FIRST_HOUR = 0x01; // 01, 02, ..., 24
const uint32_t SECS_PER_HOUR = 3600; // 3600 secs per hour
uint32_t CalcDaiBaseTimestamp(uint32_t in_ts) {
time_t ts = in_ts;
struct tm timeinfo = *localtime(&ts);
timeinfo.tm_hour = 0;
timeinfo.tm_min = 0;
timeinfo.tm_sec = 0;
time_t tmp_base_ts = mktime(&timeinfo);
return (uint32_t)tmp_base_ts;
}
void CalcDaiBaseTimestampAndHour(uint32_t in_ts,
uint32_t& base_ts,
uint8_t& hour_nth) {
base_ts = CalcDaiBaseTimestamp(in_ts);
hour_nth = (in_ts - base_ts) / SECS_PER_HOUR + FIRST_HOUR;
}
CalcDaiBaseTimestampAndHour 被多个线程调用。
代码用g++ (Ubuntu 4.8.4-2ubuntu1~14.04.4) 4.8.4编译,程序运行在Ubuntu 14.04 x64上。
大多数时候我的程序运行良好,但有时我会观察到一些“奇怪”的结果,如下所示:
(timestamp: 1554459477.500) -> (base: 1553990400, hour_nth: 131)
而正确的结果应该是:
(timestamp: 1554459477.500) -> (base: 1554422400 / hour_nth: 11)
因为:
1554459477.500 = 2019-04-05 10:17:57.500
base_ts = 2019-04-05 00:00:00 = 1554422400
hour_nth = 11
由于问题有时会发生,所以我认为原因可能是某些ctime 相关函数的线程安全。
什么可能导致“奇怪”的结果?请帮我解决这个问题!如果原因实际上是 ctime 相关函数的线程安全性,那么我该如何解决这个问题(例如使用一些 C++ 11 标准库)?
【问题讨论】:
-
std::localtime可能不是线程安全的(在某些实现中是这样)。请提供minimal reproducible example。 -
未来的 c++20 日期库可能会帮助您更轻松/安全地做到这一点github.com/HowardHinnant/date
-
@AlanBirtles 代码使用 g++ 4.8.4 编译并启用 C++11 标准。
-
日期库兼容c++11
-
@AlanBirtles 你能告诉我如何使用日期库解决这个问题吗?
标签: c++ multithreading thread-safety epoch ctime