language: c++
libararies: boost, pantheios
memory manager: redis
------------------------- 分割线 ------------------------------------
在第一个版本的服务器中,参照boost http server,写了如下代码片段:
Worker::Worker()
: _io_service(new boost::asio::io_service),
_work(new boost::asio::io_service::work(*_io_service)),
_p_cycle_timer(NULL)
{
}
运行正常,于是在第二个版本的服务器中,也如法炮制,写了如下代码:
Receiver::Receiver()
: _io_service(new boost::asio::io_service),
_work(new boost::asio::io_service::work(*_io_service)),
_acceptor(*_io_service, tcp::endpoint(tcp::v4(), Singleton<Config>::instance().port)),
_ctrl_acceptor(*_io_service, tcp::endpoint(tcp::v4(), Singleton<Config>::instance().ctrl_port))
{
................
}
结果服务器一运行,就报错:
shared_ptr.hpp:418: typename boost::detail::shared_ptr_traits<T>::reference boost::shared_ptr<T>::operator*() const [with T = boost::asio::io_service]: Assertion `px != 0' failed.
反复试了很久,发现问题出在这句上面:_work(new boost::asio::io_service::work(*_io_service)),
于是,更改为如下代码后运行就正常了:
Receiver::Receiver()
: _io_service(new boost::asio::io_service),
_acceptor(*_io_service, tcp::endpoint(tcp::v4(), Singleton<Config>::instance().port)),
_ctrl_acceptor(*_io_service, tcp::endpoint(tcp::v4(), Singleton<Config>::instance().ctrl_port))
{
_work = work_sptr(new boost::asio::io_service::work(*_io_service));
...............................
}
表面原因是因为Receiver是单例的,使用了Singleton,文件如下:
#ifndef _SINGLETON_H_
#define _SINGLETON_H_
template < typename T >
struct Singleton
{
struct object_creator
{
object_creator(){ Singleton < T > ::instance(); }
inline void do_nothing() const {}
};
static object_creator create_object;
public :
typedef T object_type;
static object_type & instance()
{
static object_type obj;
create_object.do_nothing();
return obj;
}
};
template <typename T>
typename Singleton<T>::object_creator
Singleton<T>::create_object;
#endif
因为存在静态方法,所以Receiver的构造函数是在main函数之前执行的,这个和上个项目的Worker不同。
把所有的初始化操作放在Init函数之内,然后再main函数中调用Init来初始化,这个问题就没有了。
根本原因还没有找到,不知道为什么使用singleton之后会带来这个bug。