5

私が書いている C/c++ サーバーのライブラリとして libuv を評価しています。プロトコルには長さのプレフィックスが付けられているため、ストリームから 32 ビット整数を読み取るとすぐに、割り当てる必要があるバッファーのサイズがわかります。ドキュメントには、uv_read_start 関数が複数回呼び出される可能性があると記載されています。

UV_EXTERN int uv_read_start(uv_stream_t*, uv_alloc_cb alloc_cb, uv_read_cb read_cb);

長さのプレフィックス付きプロトコルを使用しているため、バッファーの適切なサイズがわかったら、それを割り当てて、すべてのバイトを受信するまで後続の読み取りに再利用したいと思います。libuvでこれを行う簡単な方法はありますか? 現時点では、 uv_alloc_cb 関数がこれを処理する必要があるようです。バッファをマップなどに配置する代わりに、ストリーム オブジェクトに関連付けることはできますか?

長さのプレフィックス付きプロトコルを使用しているため、最初の 4 バイト (32 ビット) を読み取ることができるまで、ヒープにバッファーを割り当てたくありません。サイズ 4 のバッファをスタックに割り当て、実際に uv_read_cb 関数でヒープ割り当てを行うことはできますか? uv_read_cb 関数は uv_read_start 関数の一部として同期的に呼び出されますか? その場合、ストリームにまだバッファが接続されていないことがわかっている場合は、スタックに割り当てることができるはずです。

4

1 に答える 1

9

私自身の質問に答えます。libuv メーリング リストで回答を見つけました: https://groups.google.com/forum/#!topic/libuv/fRNQV_QGgaA

リンクが利用できなくなった場合は、ここに詳細をコピーします。

独自のデータ構造をハンドルにアタッチする:

ハンドルには、void* data使用できるフィールドがあります。長さとバッファを格納する補助構造を指すようにすることができます。

別の方法として、uv_tcp_t を別の構造体に埋め込んでから、container_of で埋め込み構造体を検索することもできます。これは標準の C マクロではありませんが、その定義と使用例は libuv/ ソース ツリーにあります。その利点は、ポインター演算を実行するだけで、別のレベルのポインター間接化から解放されることです。

受信バッファーのスタック割り当て:

いいえ、それは不可能です。それについて考える適切な方法は、あなたの alloc_cb が libuv がいつかデータで満たすバッファを返すということです。それがいつ起こるかという保証がないので、ストレスは「いつか」にあります。それはすぐかもしれませんし、数秒 (または数分) 先かもしれません。

于 2013-10-07T16:47:15.220 に答える