【问题标题】:C++ Chrono - How to use the duration_cast on std::atomic<long long>?C++ Chrono - 如何在 std::atomic<long long> 上使用 duration_cast?
【发布时间】:2017-11-20 12:55:13
【问题描述】:

我有一个class Bar

class Bar
{
public:
    //...
private:
    std::atomic<long long>          m_keepAlive;
}

这个class 有一些方法如下所述。

这个method 得到ms 的纪元:

long long Bar::getTimeSinceEpoch()
{
    std::chrono::time_point<std::chrono::system_clock> p = std::chrono::system_clock::now();
    const long long epoch = std::chrono::duration_cast<std::chrono::milliseconds>(p.time_since_epoch()).count();
    return epoch;
}

这个method 被另一个thread 调用并更新了我的m_keepAlive

void Bar::keepAlive() //This method is being called from other thread
{
    m_keepAlive= getTimeSinceEpoch();
}

在我的Bar class 上,我有一个方法不断调用此checkKeepAlive() 方法并检查自上次执行Bar::keepAlive() 以来是否已过去2 秒

void Bar::checkKeepAlive()
{
    auto now = std::chrono::system_clock::now();

   //COMPILATION ERROR here
    auto difference = std::chrono::duration_cast<std::chrono::milliseconds>(now - m_keepAlive); 

    auto timeMsSinceNoReply = difference.count();

    if(timeMsSinceNoReply >= 2000)
    {
        //timeout
    }
}

为了实现这一点,我创建了std::atomic&lt;long long&gt;,以便在我的班级中线程安全

但是,我得到这个编译错误:

no match for ‘operator-’ (operand types are ‘std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<long int, std::ratio<1l, 1000000000l> > >’ and ‘long long int’)

如何在std::atomic&lt;long long&gt; 上使用duration_cast

【问题讨论】:

  • 您正试图减去两种不兼容的类型。您需要确保两者是同一类型。例如,通过将一个涉及的变量转换或转换为与另一个相同的类型(它不会自动发生)。
  • 不管有没有atomic,这都行不通

标签: multithreading c++11 chrono long-long


【解决方案1】:

构建 chrono 库是为了让您保持显式和类型安全,通过使用对 std::chrono::duration::count 的所有调用,您正在滥用库。

now - m_keepAlive 在您的示例中是非法的。您的编译器会告诉您这一点。

  • now 的类型为 std::chrono::system_clock::time_point
  • m_keepAlive 的类型为 std::atomic&lt;long long&gt;

即使你把m_keepAlive改成long long,还是不行。

您需要将m_keepAlive 转换为持续时间,然后再尝试从now 中减去它。

例如:std::chrono::milliseconds(m_keepAlive.load()) 会将m_keepAlive 保存的值解释为毫秒数。

完整的表达式应该是: const auto difference = now - std::chrono::system_clock::time_point(std::chrono::milliseconds(m_keepAlive.load());

然后使用如下: if(difference &gt;= std::chrono::seconds(2)) { ... }

【讨论】:

  • 感谢@dalle,区别是正确的,但if(difference &gt;= std::chrono::seconds(2)) 无法编译,因为no match for ‘operator&gt;=’ (operand types are ‘const std::chrono::time_point&lt;std::chrono::_V2::system_clock, std::chrono::duration&lt;long int, std::ratio&lt;1l, 1000000000l&gt; &gt; &gt;’ and ‘std::chrono::seconds {aka std::chrono::duration&lt;long int&gt;}’) 如何将此持续时间与时间点进行比较?
  • @waas1919 我忘了在差异表达式中初始化time_point
  • 这正是我所需要的。谢谢!
猜你喜欢
  • 2016-07-18
  • 2015-09-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-07
  • 2012-09-28
  • 1970-01-01
相关资源
最近更新 更多