You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

macOS Ventura下两次调用ftruncate操作共享内存返回无效参数

macOS Ventura 13.3.1共享内存二次ftruncate失败问题

问题代码

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

int main()
{
    int memory_object_size = 72;
    const char* m_shm_name = "/original_mutexx";
    shm_unlink(m_shm_name);
    int firstfd = shm_open(m_shm_name, O_CREAT | O_RDWR, S_IRWXU); // > 0
        
    int res = ftruncate(firstfd, memory_object_size );
    if(res != 0)
    {
        printf("first object size :%d\n", memory_object_size);
        printf("first ftruncate error :%s\n", strerror(errno));
    }
    
    // does nothing
    // close(firstfd);
    // works if
    // shm_unlink(m_shm_name);

    int secondfd = shm_open(m_shm_name, O_RDWR, S_IRWXU); // > 0
    res = ftruncate(secondfd, memory_object_size);
    if(res != 0)
    {
        printf("second object size: %d\n", memory_object_size);
        printf("second ftruncate error: %s\n", strerror(errno));
    }
    return 1;
}

执行输出

second object size: 72
second ftruncate error: Invalid argument

解答

是否属于预期行为?

是,这是macOS共享内存实现的预期行为,属于跨平台机制差异导致的结果。

原因分析

  • macOS基于BSD的共享内存实现对ftruncate有严格约束:当共享内存对象仍被其他打开的文件描述符引用时,无法通过新打开的描述符修改其大小——哪怕是设置为相同值或尝试增大。你的代码中firstfd未关闭,对象仍被持有,因此secondfd调用ftruncate触发EINVAL(无效参数)错误。
  • Linux的共享内存机制在这一点上限制更宽松,允许多个打开的描述符存在时修改对象大小,这是两者的核心差异。

解决办法

  • 关闭第一个文件描述符后再打开第二个:取消代码中close(firstfd);的注释
  • 直接复用已打开的firstfd进行大小调整,无需重新打开共享内存
  • 若必须重新打开,先通过shm_unlink销毁原对象(注意此操作会清除已有数据,仅适用于重建场景)

内容的提问来源于stack exchange,提问作者Paltoquet

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 16:42:41