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。