多线程下boost::bind注意点


最近发生一个异常中再次验证了“what(): boost::lock_error”属于对象成员“boost::mutex m_mtx” 被销毁后的调用引用的,有时也会伴随Segment fault的发生。

第一反应自然是悬空指针的调用问题,指针指向了一个被销毁的对象,并在某个时间调用这个不存在的对象。但在前几次排查中没有发现这个问题,因为我的对象生成后一直使用shared_ptr,于是把问题扩展化,反复调试和查看boost源代码,甚至一度怀疑库的问题?

事实再一次证明了一个观点,C++的库是经过严格考验,任何问题的发生只可能是人的问题,而不是库。案发现场如下:

    async_write
(
m_socket,
boost::asio::buffer(msg.c_str(), msg.size()),
bind
(
&Games::HandSend, this,
boost::asio::placeholders::error
)
);

  

上面这个例子是一个很常见的boost.asio的异步执行代码,如果没认真看很容易忽略了bind参数中的“this”参数,这正是当前对象的指针!异步执行过程中另一个线程会持有这个"this"指针并在未知的时间里回调HandSend方法,而在持有这个指针的时间内,这个线程并不知道当前对象有可能已经被销毁,所以造成很低级的悬空指针案件。

正确的做法应该是:

    async_write
(
m_socket,
boost::asio::buffer(msg.c_str(), msg.size()),
bind
(
&Games::HandSend, shared_from_this(),
boost::asio::placeholders::error
)
);

  

在asio中使用了shared_from_this智能指针,而且这个在asio中是必须使用的,否则几乎|肯定会发生问题。这又再次让我领略到在C++中使用裸指针的危害,只不过以往没有对"this"这个指向自身的指针有过足够的重视。

转载于:https://www.cnblogs.com/lajabs/archive/2011/07/26/2116995.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值