我有一个我无法解决的小问题。我正在制作一个小型服务器来将我的系统日志消息重定向到它。这是非常基本的,但我想知道我做错了什么,因为我在调用 join ()
时一直出现以下错误:
/boost/path/shared_ptr.hpp:418: T* boost::shared_ptr< <template-parameter-1-1> >::operator->() const [with T = boost::thread]: Assertion `px != 0' failed.
代码会解释更多:
class SysLogServer
{
public:
typedef boost::shared_ptr<boost::thread> Ptr_thread;
bool Start ()
{
...
_thrd = Ptr_thread(new boost::thread (boost::bind(&SysLogServer::run, this)));
if (!_thrd.get ())
return ERROR ("Thread couldn't be instanciated.");
...
}
bool Stop ()
{
...
_thrd->join ();
...
}
private:
void run()
{
...
}
Ptr_thread _thrd;
};
非常感谢您的帮助。
PS:如果有任何改进可以更“线程安全”,请告诉我,因为我真的很感兴趣:)
编辑:
感谢您的评论,我认为 shared_ptr
确实没用,但从 boost::enable_shared_from_this
继承类以确保该类在线程结束之前没有被释放,这是不应该发生的。
Start()
当然是在 Stop()
之前调用的,我用 state
属性执行了一个简单的检查。 run()
方法只是接受连接。
class SysLogServer
{
public:
bool Start ()
{
...
_thrd = boost::thread(boost::bind(&SysLogServer::run, this)));
...
}
bool Stop ()
{
...
_thrd.join();
...
}
void run ()
{
std::cout << "Start running..." << std::endl; // never printed
// Create a socket
// Create a sockaddr_in
// Bind them together
while (!_serverStopped && !listen(sockfd, 5)) // on Stop(): _severStopped = true
{
// Get socket from accept
// Print the received data
// Close the socket given by accept
}
// close the first socket
}
boost::thread _thrd;
};
现在可以了。我之前用指针使用了几乎相同的解决方案,但没有成功,我的 friend SIGSEGV :)
编辑 2:
它不适用于指针,因为我忘记在 Stop()
中检查服务器是否已启动。 Start()
方法因其他原因而失败。
感谢您的宝贵建议
最佳答案
断言的原因并不能立即从您在此处提供的代码中清楚地看出,但是尽管如此,该代码可以得到显着改进。
您似乎正在使用 shared_ptr
,但似乎没有任何必要。 Ptr_thread
可以更改为 boost::thread
。这将导致代码更简单、更高效,并且对象生命周期更容易理解。
然后可以将代码更改为:
class SysLogServer
{
public:
bool Start ()
{
...
_thrd = boost::thread(boost::bind(&SysLogServer::run, this)));
...
}
bool Stop ()
{
...
_thrd.join();
...
}
private:
void run()
{
...
}
boost::thread _thrd;
};
如果在调用 Start()
之前调用 Stop()
,此代码仍然不正确,这是对原始代码失败的唯一明显解释。
关于C++ - boost 线程/绑定(bind)/Shared_ptr : Assert fault,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7685779/