【问题标题】:MacOS shm - Unable to get true data size in shmMacOS shm - 无法在 shm 中获得真实的数据大小
【发布时间】:2020-03-28 03:44:47
【问题描述】:

在MacOS上进行shm相关开发时,搜索到的进程如下代码所示(验证确实正确)。

但是,有一个新问题无法解决。发现ftruncatshm_fd调整内存大小时,是按照页面大小的倍数分配的。

但是这种情况下,当共享内存文件被其他进程打开时,无法正确获取到实际数据大小。获取的文件大小是页面的整数倍,追加数据时会报错。

// write     data_size = 12
char *data = "....";
long data_size = 12;

shmFD = shm_open(...);
ftruncate(shmFD, data_size);    // Actually the size actually allocated is not 12, but 4096
shmAddr = (char *)mmap(NULL, data_size, ... , shmFD, 0); 
memcpy(shmAddr, data, data_size);


// read
... 
fstat(shmFD, &sb)
long context_len_in_shm = sb.st_size;

// get wrong shm size ->   context_len_in_shm = 4096

【问题讨论】:

  • lseek(shmFD, SEEK_END, 0) 给出的长度是否正确?
  • @KenThomases 不,lseek() 总是返回 -1。我在 Linux 上使用 lseek,一切正常,但在 MacOS 上却不行

标签: macos shared-memory


【解决方案1】:

暂时使用如下结构将数据记录到shm中。写入或读取前的第一个操作是获取data_len字段的值,然后从后面确定要读取和写入的数据的长度。希望有更简洁的方式,就像Linux下使用lseek()一样。

shm mem map :

----shm mem----
struct {
    long data_len;
    data[1];
    data[2];
    ...
    data[data_len];
}
---------------

long *shm_mem = (long *)shmAddr;
long data_size = shm_mem[0];     // Before reading, you need to determine whether the shm file is empty and whether the pointer is valid. It is omitted here.

char *shm_data = (char *)&(shm_mem[1]);
char *buffer = (char *)malloc(data_size);
memcpy(buffer, shm_data, data_size);

【讨论】:

  • 如果多个进程要同时访问共享内存,您将需要(至少)使用原子操作来确保它们做正确的事情。
猜你喜欢
  • 2020-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-10
  • 2013-06-03
  • 2022-10-13
  • 2013-07-04
相关资源
最近更新 更多