3

共有メモリに保存されたオブジェクトを使用する際の良い方法を知りたいです。私が考えているオプションは次のとおりです。

  1. 共有メモリに格納されているオブジェクトのすべてのメンバー関数に volatile を追加します
  2. 反復ごとに共有メモリとの間でデータ全体をコピーします。
  3. volatile なしで共有メモリにアクセスします。

私が抱えている問題を説明しましょう:

Linux on FPGA で 2 つのプロセスを実行しています。それらは共有メモリを介してデータを通信します。バイナリ セマフォによって相互にロックされるため、一度に 1 つのプロセスだけがそのジョブを実行します。コンパイラは g++ 3.4.x です。私の現在のコードは以下のようなものです:

struct MyTime
{
  int32 dayNumber;
  int32 milliSecOfDay;
  void convert(double* answer);
};
struct MyData
{
  double var1;
  MyTime time;
};
volatile MyData* ptr;
ptr = (volatile MyData*)shmat(shmid, NULL, 0);

double answer;
ptr->time.convert(&answer);  //< ERROR(*)

*: エラー: const volatile TimeTTJ2000' as`bool TimeTTJ2000::get_Tu_UT1(double&, const int32&, const int32&) const' の this' 引数を渡すと修飾子が破棄されます

(上記のコードは説明用に作成されたものです。エラー メッセージは、MyData のサイズがはるかに大きい実際のコードからのものです。)

そのエラーを取り除くには、次のような別のメンバー関数を定義する必要があるように思えます

MyTime::convert(double* answer) volatile;

しかし、必ずしも私のものではないライブラリ内のすべての関数に「volatile」を追加する必要があるのはばかげているように思えます。

どこでも「揮発性」になるのを避けるために、1 つのプロセスがロック解除された直後に共有メモリ内のデータ全体をローカルにコピーし、プロセスがロックされる直前に共有メモリに書き戻すことができると思います。このように、私は揮発性に悩まされていませんが、それでもこれは賢明なことですか?

それとも、最初に volatile を使用せずに共有メモリ データにアクセスできますか? それは私の人生を楽にするでしょう。(私は共有メモリと volatile の経験がほとんどありません。volatile がいつ必要になるかはよくわかりません。もちろん、volatile が最適化を抑制するなどの基本は知っています。)

4

1 に答える 1

1

しかし、必ずしも私のものではないライブラリ内のすべての関数に「volatile」を追加する必要があるのはばかげているように思えます。

それが、C++ 標準が行うべきだと言っていることです。const/volatile 指定子をキャストすることはできますが、そうすることで UB を導入できます。

それとも、最初に volatile を使用せずに共有メモリ データにアクセスできますか?

はい、共有メモリにアクセスするために volatile は必要ありません。また、セマフォでアクセスをロックしているため、データをコピーする必要はありません。

FPGA が一部のメモリ (共有メモリではない) に書き込む場合は、volatile が必要になります。

于 2013-09-05T06:48:09.717 に答える