在继续当前工作的同时在Boost中调度任务

时间:2011-06-08 09:39:59

标签: scheduling boost-asio

我编写了一个TCP / IP程序,其中客户端使用普通(非Boost)套接字API;即服务器绑定和侦听,客户端连接。服务器使用pthreads一次处理多个客户端。

该程序使用OpenSSL在客户端和服务器之间交换会话密钥。

后来,我注意到,我需要定期执行“重新密钥”:会话建立后,我必须安排一个重新密钥任务,客户端和服务器就新的会话密钥达成一致

一种选择是为每个客户端创建一个新线程:新线程将休眠一段时间,然后唤醒并启动重新密钥。这个选项相当昂贵,因为每个客户端都需要是多线程的。

另一种选择是使用Boost Asio。我很遗憾我不知道这个有价值的图书馆存在;否则,我用Boost的线程和Boost的套接字编写了程序。

无论如何,我想以最小的改变来完成这项工作。起初,我误解了Asio。使用Boost's Timer 2示例,我写了这样的内容:

void rekey(const boost::system::error_code& /*e*/)
{
  // do rekey
}

...

void main()
{
//connect to server

// schedule re-key
boost::asio::io_service io;    
boost::asio::deadline_timer t(io, boost::posix_time::minutes(30));
t.async_wait(rekey);    
io.run();

// the rest of job (i.e. sending and receiving messages in a while() loop.)
}

这显然是错误的,因为Boost在io.run()阻止。我的第一个看法是async_wait的异步性质将解决问题,但显然我误解了Asio模型。

我有两个解决方案:

  1. 生成一个执行发送和接收的函数(使用普通套接字API),并将此函数添加到io对象的队列中,以便io.run()按预期工作。
  2. 使用Boost的异步套接字API重写套接字函数。
  3. 有更好的解决方案吗?无论如何,您能否帮我弄清楚如何实施最佳解决方案?

2 个答案:

答案 0 :(得分:2)

通常,io_service::run()(或导致事件发生的其他函数,如io_service::poll()io_servive::run_one()io_service::poll_one())将在自己的线程中运行。

我是boost :: asio库的主要支持者,因为一旦你习惯了它的编码,它就是一个非常优雅和强大的库。但是,如果您已经编写了大部分应用程序(并且正在工作),我建议不要仅仅为了利用boost :: asio来重写它,特别是如果您只需要某种类型的异步计时器。

既然你说每个客户端都有自己的线程,我建议使用某种类型的标记,你定期检查该线程,以指示何时需要重新密钥。

答案 1 :(得分:1)

  

使用重写套接字函数   Boost的异步套接字API。

这可能不像看起来那么艰巨。 documentation包括从BSD套接字API到Boost.Asio的良好映射。