我正在审查一些代码,并对所使用的技术感到怀疑。

在 linux 环境中,有两个进程附加多个
共享内存段。第一个进程周期性地加载一个新的集合
要共享的文件,并将共享内存 ID (shmid) 写入
“主”共享内存段中的一个位置。第二道工序
不断读取这个“主”位置并使用 shmid 附加
其他共享段。

在多 CPU 主机上,在我看来它可能取决于实现
如果一个进程试图读取内存时会发生什么
被对方写。但也许硬件级总线锁定可以防止
电线上的碎片?阅读过程是否得到了没关系
一个很快就会改变的值,只有读取被破坏才重要
既不是旧值也不是新值的东西。这是一个边缘情况:只有 32 位被写入和读取。

谷歌搜索 shmat 的东西并没有让我找到任何确定的东西
区域。

我强烈怀疑它不安全或不健全,而我真正想要的是
就像是一些指向详细描述问题的文章的指针。

最佳答案

这是合法的——因为在操作系统中不会阻止你这样做。

但它聪明吗?不,你应该有某种类型的同步。

不会有“电线上的错位”。它们将以 1 或 0 的形式出现。但是没有什么可以说在另一个进程尝试读取它们之前将写出所有位。并且无法保证它们的写入速度与读取速度。

您应该始终假设 2 个进程(或线程)的操作之间绝对没有关系。

除非您做对了,否则不会发生硬件级总线锁定。使您的编译器/库/操作系统/cpu 正确运行可能比预期更难。同步原语被写入以确保它正确发生。

锁定将使其安全,而且并不难做到。所以就去做吧。

@unknown - 自从我的答案发布以来,问题有所改变。但是,您描述的行为明显依赖于平台(硬件、操作系统、库和编译器)。

如果不给编译器特定的指令,实际上不能保证一次写出 32 位。想象一下 32 位字未在字边界上对齐的情况。这种未对齐的访问在 x86 上是可以接受的,而在 x68 的情况下,访问被 cpu 变成了一系列对齐的访问。

这些操作之间可能会发生中断。如果上下文切换发生在中间,一些位会被写入,有些则不会。砰,你死定了。

另外,让我们考虑一下 16 位 CPU 或 64 位 CPU。两者都仍然很受欢迎,并且不一定像您认为的那样工作。

因此,实际上您可能会遇到“其他一些 cpu-core 选择写入 1/2 字大小的值”的情况。如果您不使用同步,您编写的代码就好像这种类型的事情会发生一样。

现在,有多种方法可以预先编写您的文章,以确保您写出一个完整的单词。这些方法属于同步类别,创建同步原语是最好留给库、编译器、操作系统和硬件设计人员的类型。特别是如果您对可移植性感兴趣(即使您从未移植代码,您也应该如此)

关于shared-memory - 求关于共享内存锁定问题的文章,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/762288/

10-11 03:23
查看更多