公司的代码看不懂,不知道io_service和io_service::work怎么用的,遂写此程序用于学习推理验证。
//注释中的Page是指:Boost程序库完全开发指南(第三版)
#include <iostream>
#include <boost/asio.hpp>
#include <boost/function.hpp>
#include <boost/format.hpp>
void handler_fun1(const boost::system::error_code& code, int n)
{
std::stringstream ss; ss << code;
boost::format fmt("handler_fun1 cur_th_id=%ld, code=%s, n=%d");
fmt% GetCurrentThreadId() % ss.str() % n;
std::cout << fmt.str() << std::endl;
}
void handler_fun2(const boost::system::error_code& code, int n)
{
std::stringstream ss; ss << code;
auto str = (boost::format("handler_fun2 cur_th_id=%|ld|, code=%|s|, n=%|d|") % GetCurrentThreadId() % ss.str() % n).str();//。。。。
std::cout << str << std::endl;
}
int main1()
{// 请先阅读Page537关于io_service的"同步模式"和"异步模式"的讲解。
std::cout << "main_thread_id=" << GetCurrentThreadId() << std::endl;
boost::asio::io_service io;
boost::asio::signal_set sig(io);
//只需要add一次信号,io_service就会注册这个信号事件,然后,只要Ctrl+C触发了SIGINT,就会被io_service捕获。
sig.add(SIGINT);
//异步添加信号处理函数,添加一次,io_service捕获SIGINT后就会回调一次,然后就没有了,
//如果想让io_service下一次捕获SIGINT后再次回调它,需要再次添加信号处理函数。
sig.async_wait(handler_fun1);
sig.async_wait(handler_fun2);
io.run();
//io_service里面没有信号处理函数了,run函数就结束了。
return 0;
//在这个程序中,主线程提供了io_service::run的上下文。也可以创建一个线程,在这个线程里执行run函数。
}
int main2()
{
std::cout << "main_thread_id=" << GetCurrentThreadId() << std::endl;
boost::asio::io_service io;
boost::asio::signal_set sig(io, SIGINT);
typedef void(handler_type)(const boost::system::error_code&, int);
boost::function<handler_type> handler_lambda =
[&](const boost::system::error_code& code, int n)
{
sig.async_wait(handler_lambda);
sig.async_wait(handler_fun1);
sig.async_wait(handler_fun2);
auto str = (boost::format("handler_lambda cur_th_id=%1%, code=%2%, n=%3%") % GetCurrentThreadId() % code%n).str();
std::cout << str << std::endl;
};
//会按照添加函数的顺序回调函数
sig.async_wait(handler_fun1);
sig.async_wait(handler_lambda);
sig.async_wait(handler_fun2);
//回调函数全部执行完毕之前,又添加了新的回调函数。所以run函数没有结束,而是在等待下一次事件的触发。
io.run();
return 0;
}
int main3()
{
std::cout << "main_thread_id=" << GetCurrentThreadId() << std::endl;
boost::asio::io_service io;
//请阅读Page540的io_service::work的描述。
boost::asio::io_service::work wk(io);
boost::asio::signal_set sig(io, SIGINT);
sig.async_wait(handler_fun1);
sig.async_wait(handler_fun2);
io.run();
//io_service::work不会启动一个线程,但它会启动一个"工作",让io_service不退出run函数。
//io_service::work不会自动调用io_service的run函数,需要有代码显式的调用它。
//在哪个线程里面启动了run函数,回调函数的线程号就是谁的。
//本函数中,work启动的"工作"让io_service一直阻塞在run函数里。
return 0;
}
#include <boost/thread.hpp>
int main4()
{
//通用方法获取boost::thread::id的十进制的值。
boost::thread::id main_th_id = boost::this_thread::get_id();
std::stringstream ss; ss << main_th_id; std::string hex_str = ss.str();
long main_th_id_long = strtol(hex_str.c_str(), (char**)NULL, 16);
std::cout << "main_thread_id=" << main_th_id_long << std::endl;
boost::thread_group th_gp;
boost::asio::io_service io;
boost::asio::io_service::work wk(io);
boost::thread* new_th_ptr = th_gp.create_thread(boost::bind(&boost::asio::io_service::run, boost::ref(io)));
boost::thread::id new_th_id = new_th_ptr->get_id();
//重新解释内存布局的方法获取boost::thread::id的十进制的值。
unsigned id_uint = *reinterpret_cast<unsigned int*>(&new_th_id);
std::cout << "create a new thread, boost::thread::id=" << id_uint << std::endl;
boost::asio::signal_set sig(io, SIGINT);
int ctrl_c_count = 0;
typedef void(handler_type)(const boost::system::error_code&, int);
boost::function<handler_type> handler_lambda =
[&](const boost::system::error_code& code, int n)
{
if (++ctrl_c_count <= 5)
{
sig.async_wait(handler_lambda);
sig.async_wait(handler_fun1);
sig.async_wait(handler_fun2);
}
else
{// 析构io_service::work对象,停止"工作",让io_service能退出run函数。
wk.~work();
}
auto str = (boost::format("handler_lambda cur_th_id=%1%, code=%2%, n=%3%") % GetCurrentThreadId() % code%n).str();
std::cout << str << std::endl;
};
sig.async_wait(handler_fun1);
sig.async_wait(handler_lambda);
sig.async_wait(handler_fun2);
//等待线程组里的所有线程都退出。
th_gp.join_all();
return 0;
}
完。