共享内存安全,你可以同时读写,会发生什么?

Shared memory safty, could you read and write at the same time and what would happen?

我正在使用 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);

这个实现安全吗?

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

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

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

情况和多线程完全一样。为了安全地 read/write 数据,需要像互斥锁这样的安全机制。

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