Boost basic_deadline_timer在几次迭代后停止触发

时间:2016-01-31 04:06:30

标签: c++ boost timer boost-asio

我已经继承了一个项目,并且我试图将我的脑袋包裹起来 作品。我已经检查了我在截止时间期间遇到的所有基本问题 之前。

  • 在调用io_servicerun之前,是否附加了工作对象? ☑
  • 这些物品是否存活在范围内? ☑
  • 已验证我们未收到错误代码? ☑

***新数据**************

它不会在杂草中消失,它会回来并恢复正常运作。但它需要大约5到10分钟的时间。计时器本身似乎基于滴答计数计时器示例:

http://www.boost.org/doc/libs/1_47_0/doc/html/boost_asio/example/timers/tick_count_timer.cpp

此时我想知道计时器对象本身是否有问题。我总是使用正常的截止时间计时器。我认为它使用tick_count_timer独立于系统时钟,而系统时钟通常是从某个地方的网络时钟开始的。

这不是定时器重新启动的情况,因为有一个单独的路径,我没有第二次看到打印输出。

***结束新数据*********

毋庸置疑,这让我感到难过。

以下是相关方法:

void project::on_heartbeatsend_timer_elapsed(const boost::system::error_code& e)
{
    if (e != boost::asio::error::operation_aborted)
    {
        if (this->m_state!=session_state::SessionConnected)
        {
            stop("Heartbeat SEND lost connection");

#ifdef HEARTBEAT_DEBUG
            cout << "Heartbeat SEND lost connection to target: "
                << GetIP().c_str()
                << ":"
                << GetPort()
                << endl;
#endif // HEARTBEAT_DEBUG

        }
        else
        {

            size_t size = 0;
            packet_buffer_t b(construct_api_packet(SESSION_HEARTBEAT, 0, 0,NULL,size,&size));
            write(b, size);

            m_timerHeartbeatSend.cancel();

            size_t cancelled_stuff = m_timerHeartbeatSend.expires_from_now(m_heartbeatFrequency*1000);

            m_timerHeartbeatSend.async_wait(strand_.wrap(boost::bind(&project::on_heartbeatsend_timer_elapsed, 
                            shared_from_this(),
                            boost::asio::placeholders::error)));
#ifdef HEARTBEAT_DEBUG
            cout << "Heartbeat SEND to target "
                << GetIP().c_str()
                << ":"
                << GetPort()
                << " Next Heartbeat in: "
                << m_heartbeatFrequency
                << " seconds. cancelled "
                << cancelled_stuff
                << " pending operation."
                << endl;
#endif // HEARTBEAT_DEBUG
        }
    }
    else if (e.value() != 995)
    {
        stringstream evalSS;
        evalSS << e.value();

        std::string error_str = std::string("Error in on_heartbeatsend_timer_elapsed: ") + e.message() + " (" + evalSS.str() + ")";

        stop(error_str);

#ifdef HEARTBEAT_DEBUG
        cout << "Heartbeat "
            << error_str.c_str()
            << "   "
            << GetIP().c_str()
            << ":"
            << GetPort()
            << endl;
#endif // HEARTBEAT_DEBUG
    }
    else
    {
#ifdef HEARTBEAT_DEBUG
        cout << "Heartbeat Threading ending to target "
            << GetIP().c_str()
            << ":"
            << GetPort()
            << endl;
#endif // HEARTBEAT_DEBUG
    }
#ifdef HEARTBEAT_DEBUG
    cout << "finished processing this heartbeat for sending to target "
        << GetIP().c_str()
        << ":"
        << GetPort()
        << endl;
#endif
}

调试的输出如下所示:

Heartbeat RECV timer STARTED (handle_read_header) for target 127.0.0.1:50647
Heartbeat SEND to target 127.0.0.1:50647 Next Heartbeat in: 5 seconds. cancelled 0 pending operation.
finished processing this heartbeat for sending to target 127.0.0.1:50647
Heartbeat RECV timer STARTED (handle_read_header) for target 127.0.0.1:50647
Heartbeat SEND to target 127.0.0.1:50647 Next Heartbeat in: 5 seconds. cancelled 0 pending operation.
finished processing this heartbeat for sending to target 127.0.0.1:50647
Heartbeat RECV timer STARTED (handle_read_header) for target 127.0.0.1:50647
Heartbeat SEND to target 127.0.0.1:50647 Next Heartbeat in: 5 seconds. cancelled 0 pending operation.
finished processing this heartbeat for sending to target 127.0.0.1:50647
Heartbeat RECV timer STARTED (handle_read_header) for target 127.0.0.1:50647
Heartbeat RECV timer STARTED (handle_read_header) for target 127.0.0.1:50647
Heartbeat RECV timer STARTED (handle_read_header) for target 127.0.0.1:50647
Heartbeat RECV timer STARTED (handle_read_header) for target 127.0.0.1:50647
Heartbeat RECV timer STARTED (handle_read_header) for target 127.0.0.1:50647
Heartbeat RECV timer STARTED (handle_read_header) for target 127.0.0.1:50647
Heartbeat RECV timer STARTED (handle_read_header) for target 127.0.0.1:50647
Heartbeat RECV timer STARTED (handle_read_header) for target 127.0.0.1:50647

每次启动Heartbeat RECV计时器STARTED消息 从C#测试器接收心跳包,用于C#实现 API。

接下来我要做的是在调试器中进一步检查。我正在使用 Visual Studio 2013,但我很难做出正面或反面的 m_timerHeartbeatSend对象。

添加了一些调试,显示我看到的模式更好。时间戳是刻度线。

Heartbeat SEND to target 127.0.0.1:50367 Next Heartbeat in: 5 seconds. cancelled
 0 pending operation. old experation: 1672369 now expires at: 1677377 current ti
me: 1672377
finished processing this heartbeat for sending to target 127.0.0.1:50367
Heartbeat RECV timer STARTED (handle_read_header) for target 127.0.0.1:50367 at
1677307
Heartbeat SEND to target 127.0.0.1:50367 Next Heartbeat in: 5 seconds. cancelled
 0 pending operation. old experation: 1677377 now expires at: 1682385 current ti
me: 1677385
finished processing this heartbeat for sending to target 127.0.0.1:50367
Heartbeat RECV timer STARTED (handle_read_header) for target 127.0.0.1:50367 at
1682299
Heartbeat RECV timer STARTED (handle_read_header) for target 127.0.0.1:50367 at
1687306
Heartbeat RECV timer STARTED (handle_read_header) for target 127.0.0.1:50367 at
1692314
Heartbeat RECV timer STARTED (handle_read_header) for target 127.0.0.1:50367 at
1697322
Heartbeat RECV timer STARTED (handle_read_header) for target 127.0.0.1:50367 at
1702314
Heartbeat RECV timer STARTED (handle_read_header) for target 127.0.0.1:50367 at
1707321
Heartbeat RECV timer STARTED (handle_read_header) for target 127.0.0.1:50367 at
1712329
Heartbeat RECV timer STARTED (handle_read_header) for target 127.0.0.1:50367 at
1717337
Heartbeat RECV timer STARTED (handle_read_header) for target 127.0.0.1:50367 at
1722344
Heartbeat RECV timer STARTED (handle_read_header) for target 127.0.0.1:50367 at
1727352
Heartbeat RECV timer STARTED (handle_read_header) for target 127.0.0.1:50367 at
1732344
Heartbeat RECV timer STARTED (handle_read_header) for target 127.0.0.1:50367 at
1737351
Heartbeat RECV timer STARTED (handle_read_header) for target 127.0.0.1:50367 at
1742359
Heartbeat RECV timer STARTED (handle_read_header) for target 127.0.0.1:50367 at
1747367
Heartbeat RECV timer STARTED (handle_read_header) for target 127.0.0.1:50367 at
1752374
Heartbeat RECV timer STARTED (handle_read_header) for target 127.0.0.1:50367 at
1757366
Heartbeat RECV timer STARTED (handle_read_header) for target 127.0.0.1:50367 at
1762374
Heartbeat RECV timer STARTED (handle_read_header) for target 127.0.0.1:50367 at
1767382
Heartbeat RECV timer STARTED (handle_read_header) for target 127.0.0.1:50367 at
1772389
Heartbeat RECV timer STARTED (handle_read_header) for target 127.0.0.1:50367 at
1777397
Heartbeat RECV timer STARTED (handle_read_header) for target 127.0.0.1:50367 at
1782405
Heartbeat RECV timer STARTED (handle_read_header) for target 127.0.0.1:50367 at
1787412
Heartbeat RECV timer STARTED (handle_read_header) for target 127.0.0.1:50367 at
1792404
Heartbeat RECV timer STARTED (handle_read_header) for target 127.0.0.1:50367 at
1797412
Heartbeat SEND to target 127.0.0.1:50367 Next Heartbeat in: 5 seconds. cancelled
 0 pending operation. old experation: 1682385 now expires at: 1805001 current ti
me: 1800001
finished processing this heartbeat for sending to target 127.0.0.1:50367
Heartbeat RECV timer STARTED (handle_read_header) for target 127.0.0.1:50367 at
1802419
Heartbeat SEND to target 127.0.0.1:50367 Next Heartbeat in: 5 seconds. cancelled
 0 pending operation. old experation: 1805001 now expires at: 1810009 current ti
me: 1805009
finished processing this heartbeat for sending to target 127.0.0.1:50367

但现在我又被卡住了。我觉得我需要以某种方式检查m_timerHeartBeatSend的内部结构,以便更进一步。

1 个答案:

答案 0 :(得分:1)

原来问题出在为此计时器定义的time_traits结构中。它使用的是无符号数学,当减去的值大于另一个值时,它将计时器全部拧到了一起。最终它会恢复。如果您在代码库中看到类似的问题,请确保您的特征允许负值。