boost :: asioを使用して、async_acceptを使用して接続を受け入れます。これはうまく機能しますが、1つの問題があり、それに対処する方法の提案が必要です。典型的なasync_acceptの使用:
Listener::Listener(int port)
: acceptor(io, ip::tcp::endpoint(ip::tcp::v4(), port))
, socket(io) {
start_accept();
}
void Listener::start_accept() {
Request *r = new Request(io);
acceptor.async_accept(r->socket(),
boost::bind(&Listener::handle_accept, this, r, placeholders::error));
}
正常に動作しますが、問題があります。リクエストオブジェクトはプレーンな新規で作成されるため、メモリ「リーク」が発生する可能性があります。実際にはリークではなく、プログラムの停止時にのみリークしますが、valgrindを幸せにしたいです。
確かにオプションがあります:それをshared_ptrに置き換えて、すべてのイベントハンドラーに渡すことができます。これは、プログラムが停止するまで機能します。asioio_serviceが停止すると、すべてのオブジェクトが破棄され、リクエストが解放されます。しかし、この方法では、リクエストに対して常にアクティブなasioイベントが必要です。そうしないと、破棄されます。クラッシュする直接的な方法だと思うので、私もこのバリアントが好きではありません。
UPD 3番目のバリアント:Listener
アクティブな接続へのshared_ptrのリストを保持します。見栄えが良く、より良い方法が見つからない限り、これを使用することを好みます。欠点は、このスキーマではアイドル状態の接続で「ガベージコレクション」を実行できるため、安全ではありません。リスナーから接続ポインタを削除すると、すぐに破棄され、接続のハンドラの一部が他のスレッドでアクティブな場合にセグメンテーション違反が発生する可能性があります。mutexを使用すると、このcusを修正できません。この場合、ほぼすべてをロックする必要があります。
アクセプターを接続管理で機能させる方法はありますか?美しく安全な方法はありますか?何か提案を聞いてうれしいです。