peakzhang 发表于 2007-12-12 23:53:40

使用proactor的应用如何在退出时避免内存泄漏?

我的应用使用proactor模式,当应用退出时,调用end_event_loop先结束proactor事件处理循环.
然而如果此时有一个未完成的write调用,则会导致内存泄漏.(vc 2003下报告内存泄漏).
我的问题是:
1. 如果取消一个未完成的write调用?
2. 关闭proactor时,如何获取该未完成write调用持有的message block(从而释放其内存)?
谢谢!

peakzhang 发表于 2007-12-12 23:53:47

尝试调用异步处理对象的cancel()方法,不过未必成功。
我认为,不必关心异步发起产生的所谓“泄露”,无关紧要。因为系统已经停止运行,OS会自动回收。
再者,异步发起的请求,在得到处理的时候,就没有泄露了。

peakzhang 发表于 2007-12-12 23:53:55

>尝试调用异步处理对象的cancel()方法,不过未必成功。
是什么意思?调用ACE_Asynch_Read_Stream的cancel方法吗?不过未必成功是什么意思?

>不必关心异步发起产生的所谓“泄露”,无关紧要。因为系统已经停止运行,OS会自动回收。

是这样。我是想得到一个完美的解决方案。最好是能够解决该问题。

peakzhang 发表于 2007-12-12 23:54:44

这是我曾经的一段代码的简化版,应该能很好的解决你的问题:

class MY_Handler : public ACE_Service_Handler
{
public:
MY_Handler(void)
    : mblk_ (0)
{}

virtual ~DH_Handler(void)
{ this->destroy (); }

// Called by ACE_Asynch_Acceptor when a client connects.
virtual void open (ACE_HANDLE new_handle,
                     ACE_Message_Block &message_block)
{
   reader_.open (*this, new_handle, 0, proactor ());
   writer_.open (*this, new_handle, 0, proactor ());
   
   ACE_NEW_NORETURN (mblk_,
                     ACE_Message_Block (ACE_DEFAULT_CDR_BUFSIZE));
   // Align the Message Block for a CDR stream
   ACE_CDR::mb_align (mblk_);
   reader_.read (*mblk_, 自定义长度);
}

protected:
// Handle input from clients.
virtual void handle_read_stream (const ACE_Asynch_Read_Stream::Result &result)
{
   if (!result.success () || result.bytes_transferred () == 0)
   delete this;
   else if (result.bytes_transferred () < result.bytes_to_read ())
   reader_.read (*mblk_,
                   result.bytes_to_read () - result.bytes_transferred ());
   else
   writer_.write (*mblk_,
                   mblk_.size ());
}

// Handle output to clients.
virtual voidhandle_write_stream (const ACE_Asynch_Write_Stream::Result &result)
{
   if (!result.success () || result.bytes_transferred () == 0)
   delete this;
   else
   {
    mblk_.reset ();
    // Align the Message Block for a CDR stream
    ACE_CDR::mb_align (mblk_);
    reader_.read (*mblk_, 自定义长度);
   }
}

// Called by destructor to release all resources. Can be override by sub class.
virtual void destroy (void)
{
   reader_.cancel ();
   writer_.cancel ();
   ACE_OS::closesocket (handle ());
   if (mblk_ != 0)
   mblk_->release ();
   mblk_ = 0;
}

protected:
ACE_Message_Block *mblk_;       // Block to received
ACE_Asynch_Read_Stream reader_; // Async read factory
ACE_Asynch_Write_Stream writer_; // Async write factory
};

这个例子简单的从客户端读取一段数据流然后原封不动的返回给客户端,在对端关闭连接或handler的创建者手动关闭连接的时候,都只需要简单的删除维护该连接的handler就可以,handler自动清理socket句柄和ACE_Message_Block数据块,并cancel异步读写单元。

最后,在主线程结束的时候,你只需要在发起proactor的end_event_loop请求的同时,枚举并删除每个handler对象,然后调用ACE_Thread_Manager的wait等待正在进行中的异步动作的结束,就可以完全安全并无泄漏的终止你的应用。
页: [1]
查看完整版本: 使用proactor的应用如何在退出时避免内存泄漏?