【问题标题】:Boost Threads and Timers, C++提升线程和定时器,C++
【发布时间】:2009-08-27 15:35:41
【问题描述】:

我有这个自定义类“sau_timer”的代码:

sau_timer::sau_timer(int secs, timerparam f, vector<string> params) : strnd(io), 
    t(io, boost::posix_time::seconds(secs))
{
    assert(secs > 0);
    this->f = f;
    this->params = params;
    t.async_wait(strnd.wrap(boost::bind(&sau_timer::exec, this, _1)));
    boost::thread thrd(boost::bind(&boost::asio::io_service::run, &io));
    io.run();
}

void sau_timer::exec(const boost::system::error_code&) {
    (f)(params);
}

我希望这样当我创建一个 sau_timer 对象时,计时器会启动,但允许程序继续执行。例如,这是 main():

int main(int argc, char* argv[])
{
    vector<string> args(1);
    args[0] = "Hello!";
    sau_timer timer_test(3, sau_prompt, args);
    args[0] = "First!";
    sau_prompt(args);
    timer_test.thrd.join();
    return 0;
}

我的意图是创建 timer_test,启动一个等待三秒钟的计时器,然后再调用 sau_prompt("Hello!"),但将首先调用 sau_prompt("First!")。此时,在 First 之前的提示符中显示 Hello,表示计时器正在暂停整个程序三秒钟,然后才允许它继续。我希望计时器在后台运行。

我做错了什么?代码编译...

谢谢。

【问题讨论】:

    标签: c++ multithreading boost timer boost-asio


    【解决方案1】:

    您在 sau_timer 中调用“io.run()” - 这实际上是告诉 asio 反应器处理任何/所有挂起的异步事件(如果可以)。

    您应该在设置完事件后调用 run 或 post,这通常是这样做的。查看 asio 文档中的示例。

    #include #include #include #include #include #include #include 类 event_timer { 上市: event_timer(asio::io_service& io_service, 常量 std::size_t& tid, const std::size_t& 间隔 = 5) : io_service_(io_service), timer_(io_service), tid_(tid), 间隔_(间隔), tick_count_(0), total_diff_(0) { } 无效的开始() { timer_.cancel(); 启动定时器(); } 无效停止() { timer_.cancel(); } void set_interval(const std::size_t& 毫秒) { 间隔_ = 毫秒; } 私人的: 内联无效initial_timer() { 如果(间隔_) { timer_.expires_from_now(boost::posix_time::milliseconds(interval_)); timer_.async_wait( boost::bind(&event_timer::handle_timer_event,this, asio::placeholders::error)); before_ = boost::posix_time::microsec_clock::universal_time(); } } 内联 void handle_timer_event(const asio::error_code& 错误) { if (!error && interval_) { after_ = boost::posix_time::microsec_clock::universal_time(); boost::posix_time::time_duration 持续时间 = after_ - before_; total_diff_ += std::abs(interval_ - duration.total_milliseconds()); ++tick_count_; 如果 (tick_count_ et_lst; for(无符号整数 i = 0; i start(); } std::size_t 线程池大小 = 100; //创建一个线程池来运行所有的io_services。 std::vector<:shared_ptr> > 线程; for (std::size_t i = 0; i 线程(新的 boost::thread(boost::bind(&asio::io_service::run, &io_service))); 线程.push_back(线程); } // 等待池中的所有线程退出。 for (std::size_t i = 0; i join(); for(unsigned int i = 0; i

    【讨论】:

    • 我把 timer_test.io.run();在 sau_timer timer_test(3, sau_prompt, args) 行下;在 main() 中,并从类构造函数中删除了 io.run(),但效果还是一样的。恐怕我误会了?
    • 示例代码应该足以让您了解一般应该如何使用 asio。您看到的想法不是创建线程来运行对象,例如计时器或接收器对象,而是创建多个运行 io_services 的线程,并让这些线程化 io_services 以线程/并发方式运行异步调用。
    【解决方案2】:

    考虑到命名空间和boost版本1.69,应该做三处修改:

    1. 将#include &lt;asio.hpp&gt; 更改为#include &lt;boost/asio.hpp&gt;
    2. 添加:using namespace boost; using namespace boost:asio;
    3. 将inline void handle_timer_event(const asio::error_code&amp; error) 更改为void handle_timer_event(const boost::system::error_code&amp; error)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多