c++ - 是什么让我的 C++ ctime 相关函数行为异常?

标签 c++ multithreading thread-safety epoch ctime

我创建了两个函数来计算给定纪元时间戳的一天的开始时间戳(即一天的 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 标准库)?

最佳答案

Could you please show me how to work around this using the date library?

引用链接:https://github.com/HowardHinnant/date

代码:

#include "date/date.h"
#include <iomanip>
#include <iostream>

int
main()
{
    using namespace std::chrono;
    using namespace date;
    using dsec = duration<double>;
    sys_time<dsec> tp{dsec{1554459477.500}};
    std::cout << std::setprecision(3) << std::fixed
              << tp.time_since_epoch().count()
              << " = " << round<milliseconds>(tp) << '\n';
    sys_seconds base_ts = floor<days>(tp);
    std::cout << "base_ts = " << base_ts << " = "
              << base_ts.time_since_epoch().count() << '\n';
    auto hour_nth = floor<hours>(tp - base_ts) + hours{1};
    std::cout << "hour_nth = " << hour_nth.count() << '\n';
}

输出:

1554459477.500 = 2019-04-05 10:17:57.500
base_ts = 2019-04-05 00:00:00 = 1554422400
hour_nth = 11

注意事项:

关于c++ - 是什么让我的 C++ ctime 相关函数行为异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55536455/

相关文章:

.net - Dispose 方法的线程安全性?

javascript - 跳过了 773 帧!应用程序可能在其主线程上做了太多工作。 [安卓网页浏览]

c++ - 为什么以前杀死的boost线程的线程ID被分配给新的boost线程?

c++ - 如果线程涉及互斥锁定和解锁之间的循环,则在 C++ 中的 2 个线程之间切换执行

c++ - 是否喜欢更长的生命周期/更大范围的局部变量?

c# - 异步 Web Request、EntityFramework 和 DI,是如何工作的?

c++ - 从独立的 TU 零碎地构建静态数据结构

c++ - “#define X X”是什么意思?

c++ - 为什么 `printf("%llu\n", 1ull << n) ;` and ` printf ("%llu\n", 1ull << 64);` 的输出在 C++ 中不同?(n=64)

c++ - 使用 dcmtk 覆盖 dicom 文件中的图像/像素数据