【问题标题】:Shared memory safty, could you read and write at the same time and what would happen?共享内存安全,你可以同时读写吗?会发生什么?
【发布时间】:2020-11-02 12:09:08
【问题描述】:

我正在使用 sys/shm 库在两个应用程序之间共享内存。 它运行良好,如我所愿,但我不确定该库是否以我目前实现的方式完全安全。

如果在另一个应用程序尝试读取它的同时更改了一个值会发生什么。这甚至可能首先发生吗?我不知道。

这是我的两个应用程序的简化版本:

发送:

int main(int argc, char* argv[])
{
    int Delta_x{ atoi(argv[1]) }, Delta_y{ atoi(argv[2]) }, Delta_z{ atoi(argv[3]) };

    int shmid;
    int* array;
    int count = 3;
    int i = 0;
    int SizeMem;
    key_t key = ftok("shmfile", 66);

    SizeMem = sizeof(*array) * count;
    shmid = shmget(key, count * sizeof(int), IPC_CREAT);
    array = (int*)shmat(shmid, 0, 0);


    array[0] = Delta_x;
    array[1] = Delta_y;
    array[2] = Delta_z;

    shmdt((void*)array);
    return 0;
}

收到:

int* Recieve;
int x{ 0 }, y{ 0 }, z{0};

key_t key = ftok("shmfile", 66);
int shmid = shmget(key, 3 * sizeof(int), IPC_EXCL);
Recieve = (int*)shmat(shmid, (void*)0, SHM_RDONLY);

while (Condition)
{
    x = Recieve[0];
    y = Recieve[1];
    z = Recieve[2];
    std::cout << "x:" << x << ", y:" << y << ", z:" << z << std::endl;
    usleep(50000);
}

shmdt((void*)Recieve);

这个实现安全吗?

【问题讨论】:

  • 不,这不安全。对共享内存段的并发访问是未指定的行为。您将不得不自己进行一些研究,以调查在您的实现中是否有可能在共享内存中构造一个互斥锁(使用placement new),并使用它来同步对其余共享内存的访问。

标签: c++ memory shared-memory


【解决方案1】:

这不安全。 我的意思是,如果您将写入代码放在一个循环中并运行发送代码,则读取代码可能会在第一次写入之后和最后一次写入之前执行。 它根据线程调度程序。

但是您在共享内存中的数据是整数值。它可以在一条指令中写入和读取,因此您从内存中读取的值始终是您写入的值。

并且读/写一个有效的整数永远不会导致程序崩溃。

【讨论】:

    【解决方案2】:

    情况与多线程中的情况完全相同。为了安全地读/写数据,需要像互斥锁这样的安全机制。

    Boost.Interprocess 库具有各种互斥体、信号量和条件变量。只是不要期望它们高效,因为大多数操作系统对交互处理的支持一直非常有限。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-19
      • 2015-01-19
      • 1970-01-01
      • 2011-09-23
      • 1970-01-01
      • 1970-01-01
      • 2016-09-07
      • 1970-01-01
      相关资源
      最近更新 更多