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

时间:2019-04-05 13:25:04

标签: c++ multithreading thread-safety epoch ctime

我做了两个函数,分别计算给定纪元时间戳的一天的开始时间戳(即一天的00:00:00)和小时(从1到24)。

{
  "avaliabilitiesResponse": {
    "Hotels": {
      "Hotel": [
        {
          "HotelCode": "0017855",
          "HotelsName": "Hilton Jeddah",
          "Location": "Jeddah, Saudi Arabia",
          "Rating": "4",
          "LowestPrice": "35",
          "Currency": "EUR",
          "IsReady": "true",
          "AvailableRooms": 
            [
              {
                "RoomCode": "11245",
                "RoomName": "Standard",
                "Occupancy": "1",
                "Status": "true"
              },
              {
                "RoomCode": "12000",
                "RoomName": "Double",
                "Occupancy": "2",
                "Status": "true"
              },
              {
                "RoomCode": "99685",
                "RoomName": "Twin",
                "Occupancy": "2",
                "Status": "true"
              }
            ]
          }
        ,
        {
          "HotelCode": "0018799",
          "HotelsName": "Ramada Continental Jeddah",
          "Location": "Jeddah, Saudi Arabia",
          "Rating": "3",
          "LowestPrice": "345",
          "Currency": "USD",
          "IsReady": "false",
          "AvailableRooms" :  
            [
              {
                "RoomCode": "00012",
                "RoomName": "Triple Standard",
                "Occupancy": "3",
                "Status": "false"
              },
              {
                "RoomCode": "5477",
                "RoomName": "Triple Sea View",
                "Occupancy": "3",
                "Status": "false"
              },
              {
                "RoomCode": "996666",
                "RoomName": "Standard Double",
                "Occupancy": "2",
                "Status": "true"
              }
            ]

        },
        {
          "HotelCode": "0010888",
          "HotelsName": "Qasr Al Sharq",
          "Location": "Jeddah, Saudi Arabia",
          "Rating": "5",
          "LowestPrice": "3500",
          "Currency": "SAR",
          "IsReady": "true",
          "AvailableRooms": [
            {
              "RoomCode": "102432",
              "RoomName": "Suite",
              "Occupancy": "4",
              "Price": "3500",
              "Status": "true"
            }
          ]
        }
      ]
    }
  }
}
从多个线程中调用

#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相关的函数的线程安全,那我该如何解决(例如使用某些C ++ 11标准库)?

1 个答案:

答案 0 :(得分:3)

  

您能告诉我如何使用日期库解决此问题吗?

参考链接: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

注意: