3

我想知道使用存储在共享内存中的对象的好习惯是什么。我心中的选择是:

  1. 向存储在共享内存中的对象的每个成员函数添加 volatile
  2. 在每次迭代时将整个数据从共享内存复制到共享内存。
  3. 访问没有 volatile 的共享内存。

让我解释一下我遇到的问题:

我有两个在 FPGA 上的 Linux 上运行的进程。它们通过共享内存进行数据通信。由于它们通过二进制信号量相互锁定,因此一次只有一个进程完成其工作。编译器是 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' 的参数会丢弃限定符

(上面的代码只是为了解释,错误信息来自我的真实代码,其中MyData的大小要大得多。)

要消除该错误,在我看来,我必须定义另一个成员函数,例如

MyTime::convert(double* answer) volatile;

但在我看来,我必须将“volatile”添加到库中不一定是我的所有函数中,这似乎很荒谬。

为了避免到处都有“易失性”,我想我可以在一个进程被解锁后立即将共享内存中的全部数据复制到本地,并在进程被锁定之前写回共享内存。这样一来,我就不再为 volatile 所困扰了,但这仍然是明智之举吗?

或者我可以在不首先使用 volatile 的情况下访问共享内存数据吗?那会让我的生活更轻松。(我在共享内存和 volatile 方面的经验很少。我不太确定何时需要 volatile。当然我知道基础知识,比如 volatile 会抑制优化。)

4

1 回答 1

1

但在我看来,我必须将“volatile”添加到库中不一定是我的所有函数中,这似乎很荒谬。

这就是 c++ 标准所说的应该做的事情。您可以抛弃 const/volatile 说明符,但这样做,您可能会引入 UB。

或者我可以在不首先使用 volatile 的情况下访问共享内存数据吗?

是的,您不需要 volatile 来访问共享内存。而且由于您使用信号量锁定访问,因此您不需要复制数据。

如果您的 FPGA 写入某些内存(不是共享内存),您将需要 volatile。

于 2013-09-05T06:48:09.717 回答