当 asio::async_write 不调用处理程序时该怎么办?
What to do when asio::async_write doesn't call the handler?
在一个类中有以下两个成员函数。_mtxWrite是我用来使写函数线程安全的互斥对象。在高负载期间,有时不会调用writeHandler。然后_mtxWrite不会被释放,导致死锁。检测这种情况并解决僵局的最佳方法是什么?
template <class TSession>
void write(boost::shared_ptr<TSession> pSession,
boost::shared_ptr<CInProtocolBase> pMessage)
{
std::vector<unsigned char>* pData = new std::vector<unsigned char>;
pMessage->serialize(*pData);
_mtxWrite.lock();
boost::asio::async_write(_socket,boost::asio::buffer(&pData->at(0),
pData->size()),
boost::bind(&this_type::writeHandler<TSession>,
shared_from_this(),pSession,pData,boost::asio::placeholders::error));
}
template <class TSession>
void writeHandler(boost::shared_ptr<TSession> pSession,
std::vector<unsigned char>* pData,const boost::system::error_code& ec)
{
delete pData;
_mtxWrite.unlock();
if(ec)
{
_socket.get_io_service().post(boost::bind(&TSession::errorHandler,
pSession,ec));
}
}
您的代码正在锁定一个互斥锁,其中async_write()
被调用并在处理程序中解锁它。如果这些操作发生在不同的线程中,那么这将违反unlock()
前提条件(当前线程拥有互斥锁)。这可能会导致死锁。通常,分离的锁定和解锁通常是次优设计的指示。
处理异步写操作的更好方法是使用队列。逻辑看起来像这样:
写功能:
- 锁定互斥对象。
- Push buffer到queue.
- 如果队列只包含一个元素,则调用前面元素的
async_write
。 - 解锁互斥锁(理想情况下通过
scoped_lock
落在范围之外)。
编写处理程序:
- 锁定互斥对象。
- 从队列中弹出缓冲区(并释放它)
- 如果队列不为空,则调用前面元素的
async_write
。 - 解锁互斥锁(理想情况下通过
scoped_lock
退出范围)。
使用这种方法锁定是本地化的,没有死锁的机会。@TannerSansbury在注释中指向使用链来同步而不是互斥锁的指针的工作原理类似——它隐式地为在链中运行的任何函数提供了排斥。
我从来没有遇到过写处理程序没有被调用的情况,最终确定这不是我自己的错误,但是您可以使用boost::asio::deadline_timer来监视这种情况,通过在调用async_write()
时设置计时器并在写处理程序中取消它。
相关文章:
- Mongodb c++驱动程序:如何查询元素的数组
- C++,系统无法执行指定的程序
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- 在VS代码中交叉编译Windows与Linux上的MinGW的SDL程序
- C++ Windows 驱动程序MSB3030无法复制该文件,因为它找不到
- 重载操作程序时出错>>用于类中的字符串 memebr
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- 试图在visual studio上用C++创建一个桌面应用程序
- 当您的程序在进入主程序之前崩溃时该怎么办?
- 如果我在 Xbox UWP 应用程序上收到激活错误并且错误消息中没有任何有用的内容,该怎么办
- Linux C++程序以一个仍在运行的线程结束后该怎么办
- 当来自外部库的线程不可预测地崩溃我的应用程序时,我该怎么办
- 在一个非常简单的程序中检测到内存泄漏.怎么办
- dev 我刚刚开始使用 DEV C++编译器。一些在涡轮编译器中运行良好的程序在开发编译器中没有运行。怎么办?
- 如何为一个c++程序提供测试用例,如果QA部门拒绝它怎么办?
- 如果一个堆叠的协同程序锁定了一个互斥对象,然后就屈服了,该怎么办
- 当应用程序开始耗尽内存时该怎么办?
- 当 asio::async_write 不调用处理程序时该怎么办?
- 简单的 OpenCV 程序无法运行;没有错误。现在怎么办?
- OpenCV/C++程序比numpy程序慢,我该怎么办