4

私はboost::asioで作業しています。ソケットからの非同期読み取りを担当するクラスを作成しました。私のアプリケーションでは、1 回のアプリケーション実行中に io_service を何度も停止および開始できます。そのため、サービスが停止したときのメモリ リークを心配する必要があります。私は2つの解決策に行き着きました:

  1. 非同期リクエストを要求するクラスは、asio 読み取りで使用するためのバッファーを関数に提供し、その解放を担当します。これは明らかな解決策ですが、私は好きではありません。必要のないパラメーターを関数に渡すのは、非常に奇妙に見えます。

  2. コールバックにバインドされたスマート ポインター。例: http://pastebin.com/p8nQ5NFi

今、私は2番目の解決策を使用していますが、私は車輪を発明しています。非同期呼び出しでのバッファ クリーンアップの一般的な方法は何ですか? 私のアプローチに隠れた問題はありますか?

4

1 に答える 1

4

shared_ptrアプローチはかなり一般的です。ただし、 にshared_ptr追加の引数としてa を渡す代わりに、 の代わりにインスタンス オブジェクトとしてbindを渡すことができます。shared_ptrthis

boost::shared_ptr< my_class > ptr( this );

boost::asio::async_read( stream, buffer, 
  boost::bind( &my_class::read_handler, ptr, 
     boost::asio::placeholders::error
     boost::asio::placeholders::bytes_transferred ) );

多くの場合、インスタンスは を介し​​て管理されるためshared_ptr、 のコンテキストにある場合とない場合があるため、thisBoost.SmartPointer の を使用することをお勧めしますenable_shared_from_this。クラスが から継承する場合、有効なインスタンスを に返すメンバー関数をboost::enable_shared_from_this提供します。shared_from_this()shared_ptrthis

class my_class: public boost::enable_shared_from_this< my_class >
{
  void read()
  {
     boost::asio::async_read( stream, buffer, 
       boost::bind( &my_class::read_handler, shared_from_this(), 
          boost::asio::placeholders::error
          boost::asio::placeholders::bytes_transferred ) );
  }
};

boost::shared_ptr< my_class > foo( new my_class() );
foo->read();

このスニペットではfoo.get()foo->shared_from_this()両方が同じインスタンスを指しています。これにより、特定が困難なメモリ リークを防ぐことができます。たとえば、元のサンプル コードでは、を呼び出そうとすると、 Protocol::AsyncReadMessageifの copy-constructor throws でメモリ リークが発生します。Boost.Asio の非同期 TCP デイタイム サーバーと多くのは、Boost.Asio 内で使用されていることを示しています。理解を深めるために、この質問では特に非同期の Boost.Asio 関数と.AsyncReadHandlerAsyncReadMessageenable_shared_from_thisshared_ptr


Protocol::AsyncHelperまた、元のコードでは、テンプレート メンバー関数を持つ非テンプレート クラスにするよりも、テンプレート クラスを作成する方が簡単な場合があります。これにより、AsyncHelperはプロトコル、ストリーム、およびハンドラーをコンストラクター引数として受け入れ、それらをメンバー変数として格納できます。さらに、bind渡す必要がある引数の量が減り、メンバー関数がテンプレートでなくなるため、完全な型を指定する必要がないため、呼び出しが少し読みやすくなります。 ここに例の簡単なパスがあります。

于 2012-07-25T22:10:12.317 に答える