C语言 通过shm_open和mmap共享内存:当从共享内存中阅读时,如何避免线程或进程本地缓存?

ggazkfy8  于 2023-06-21  发布在  其他
关注(0)|答案(1)|浏览(95)

我使用shm_open + mmap来编写一个消费者和一个生产者,它们通过共享内存交换数据。消费者在一个过程中,生产者在另一个过程中。一切都很好,但是我如何确保我的消费者不会一直阅读缓存内存(线程/进程本地缓存),而不是生产者写入的最新内容?
下面是我的消费者C代码:

#include <stdio.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

#define STORAGE_ID "/SHM_TEST"
#define STORAGE_SIZE 32

int main(int argc, char *argv[])
{
    int res;
    int fd;
    char data[STORAGE_SIZE];
    pid_t pid;
    void *addr;
    
    pid = getpid();
     
    // get shared memory file descriptor (NOT a file)
    fd = shm_open(STORAGE_ID, O_RDONLY, S_IRUSR | S_IWUSR);
    if (fd == -1)
    {
        perror("open");
        return 10;
    }
     
    // map shared memory to process address space
    addr = mmap(NULL, STORAGE_SIZE, PROT_READ, MAP_SHARED, fd, 0);
    if (addr == MAP_FAILED)
    {
        perror("mmap");
        return 30;
    }
     
    // place data into memory
    memcpy(data, addr, STORAGE_SIZE);
    
    printf("PID %d: Read from shared memory: \"%s\"\n", pid, data);
     
    return 0;
}
yyhrrdl8

yyhrrdl81#

我如何确保我的消费者不会一直阅读缓存内存(线程/进程本地缓存),而不是生产者写入的最新内容?
通过使用适当的同步对象(其本身可能存在于共享内存中,尽管存在其他选项)来同步对共享内存的访问。@AndrewHenle在评论中讨论了这一点。一个进程共享的互斥体将是自然的选择,因为您很可能希望使用一个(进程共享的)条件变量,这将需要一个互斥体。
您需要应用适当的同步来获得任何类型的有用程序语义,如果您应用了适当的同步,那么也会处理任何缓存/内存排序问题。因此,即使您“一次做一步”,正如您在注解中所说的那样,确保正确的同步和确保写入的可见性也不是单独的步骤。

相关问题