3

配列をファイル記述子に送信するかなり単純な関数を作成しています。ただし、データを送信するには、1 バイトのヘッダーを追加する必要があります。

これは私がやっていることの簡略化されたバージョンであり、うまくいくようです:

void SendData(uint8_t* buffer, size_t length) {
  uint8_t buffer_to_send[length + 1];
  buffer_to_send[0] = MY_SPECIAL_BYTE;
  memcpy(buffer_to_send + 1, buffer, length);
  // more code to send the buffer_to_send goes here...
}

私が言ったように、コードは問題なく動作するようですが、現在のプロジェクトにはスタイル ガイドが設定されていないため、最近は Google C++ スタイル ガイドを使用する習慣を身につけています (実際、私は私の唯一のソフトウェア エンジニアです)。プロジェクトであり、業界で使用されているものを使用したかった)。Google の cpplint.py を実行したところ、buffer_to_send を作成している行がキャッチされ、可変長配列を使用しないというコメントが投げられました。具体的には、Google の C++ スタイル ガイドが可変長配列について述べていることは次のとおりです...

http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Variable-Length_Arrays_and_alloca__

彼らのコメントに基づいて、コード内のランダムに見えるクラッシュの根本原因を見つけたようです (非常にまれにしか発生しませんが、それでも迷惑です)。しかし、私はそれを修正する方法について少し引き裂かれています。

私が提案する解決策は次のとおりです。

  1. buffer_to_send を本質的に一定長の固定長配列にします。ここで考えられる問題は、送信したい理論上最大のバッファーと同じ大きさのバッファーを作成する必要があることです。平均的なケースでは、バッファーははるかに小さく、関数が呼び出されるたびに約 0.5KB を浪費することになります。プログラムは組み込みシステムで実行する必要があることに注意してください。必ずしも各バイトをカウントしているわけではありませんが、使用するメモリはできるだけ少なくしたいと考えています。

  2. new と delete または malloc/free を使用して、バッファーを動的に割り当てます。ここでの問題は、関数が頻繁に呼び出され、OS に常にメモリを要求してから解放するという点でオーバーヘッドが発生することです。

  3. データをファイル記述子に渡すには、write() を 2 回連続して呼び出します。つまり、最初の書き込みでは 1 バイトのみが渡され、次の書き込みでは残りのバッファーが送信されます。簡単そうに見えますが、2 つの連続する書き込みがアトミックに行われることを保証するために、コードをもう少し調査する必要があります (このコードは、私が勤務していた会社を退職した前のエンジニアから受け継いだものです)。また、ロックが必要な場合は、基本的にケース 2 よりも複雑になり、パフォーマンスへの影響が大きくなります。

buffer_to_send をメンバー変数にしたり、関数の範囲外にスコープしたりすることはできないことに注意してください。これは、さまざまなスレッドからいつでも関数への複数の呼び出しが (潜在的に) あるためです。

あなたの意見と、私が好むアプローチを教えてください。御時間ありがとうございます。

4

2 に答える 2

3

オプション 3 の write() への 2 つの連続した呼び出しを、writev() を使用して 1 つの呼び出しに折りたたむことができます。

http://pubs.opengroup.org/onlinepubs/009696799/functions/writev.html

于 2013-09-27T04:01:22.297 に答える
0

オプション 1 を選択します。データの最大長がわかっている場合は、固定サイズの配列を使用してスタックにその分のスペース (プラス 1 バイト) を割り当てます。これは、スタック上に常に十分なスペースが残っている必要があるため、示した可変長配列よりも悪くはありません。そうしないと、最大長を処理できなくなります (最悪の場合、コードは大きなバッファー サイズでランダムにクラッシュします)。 . この関数が呼び出された時点では、スタック上のそれ以上のスペースを使用するものは他にないため、固定サイズの配列を安全に割り当てることができます。

于 2013-09-27T03:46:09.847 に答える