检查 POSIX 共享内存对象的大小。

5

有没有办法检查由shm_open返回的文件描述符是否是当前进程创建的,还是先前存在的?此外,在这样做后,有没有办法检查它的大小?

目前我拥有的是:

if ((fd = shm_open(SHARED_OBJ_NAME, O_RDWR|O_CREAT, 0777)) == -1)
    die(1, "Failed to open shared object");

fd_size = lseek(fd, 0, SEEK_END);

printf("Shared size: %ld\n", fd_size);

if (fd_size == -1 || fd_size < SHARED_OBJ_SIZE) {
    if (ftruncate(fd, 255) == -1)
        printf("ftruncate failed\n");
    fd_size = lseek(fd, 0, SEEK_END);
}

printf("Shared size: %ld\n", fd_size);

但问题在于我总是会得到两次“共享大小:-1”的消息,只有在对象创建后立即调用ftruncate才不会失败。


我怀疑你不能在shm_open()返回的内容上调用lssek()。但是,如果从lseek()获取到-1,你可以添加一个调用perror()的语句来获取有关失败的详细信息。 - alk
你想通过这个实现什么目标? - fuz
1个回答

3
你可能想在共享内存的名称上使用stat(),并传入struct stat实例的地址。如果函数成功,则可以在结构体成员st_size中找到共享内存的大小。
来自POSIX文档关于stat()

如果命名的文件是共享内存对象,则实现将更新由buf参数指向的stat结构中的st_uidst_gidst_sizest_mode字段,[...]


同时,在共享内存描述符上调用lseek()会导致未指定的行为,因此可能会根据代码运行的平台产生预期或不预期的结果。为了保持代码的可移植性,请勿这样做。

lseek()的POSIX文档中得知:

如果fildes是指向共享内存对象,则lseek()函数的结果是未指定的。


谢谢,这个可行。你知道共享对象的大小是否必须与页面大小匹配吗?我试图将其调整为255B,但fstat告诉我它是4096B。 - wesolyromek
1
@wesolyromek,由于大多数系统只能映射整个页面,因此 POSIX 允许共享对象的大小大于您请求的大小是有意义的。 - fuz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接