【问题标题】:shm_open and ftruncate() in Shared Memory Programming共享内存编程中的 shm_open 和 ftruncate()
【发布时间】:2026-02-16 03:25:01
【问题描述】:

我想创建一个共享内存对象并将其截断为特定大小。

SHMSIZE 用 512 定义

MODE 设置为 S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IWOTH | S_IROTH

这是我的代码

char *shm_name = "SharedMemory";    
int fd; 

/* Open an Shared Memory Object for Read-/Write-Access */    
if((fd = shm_open(shm_name, O_RDWR | O_CREAT, MODE) < 0)) {     
     perror("\nshm_open() in Caretaker failed");    
     exit(EXIT_FAILURE);
}

/* Truncate Shared Memory Object to specific size */
if((ftruncate(fd, SHMSIZE) < 0)) {
    perror("\nftruncate() in Caretaker failed");
    exit(EXIT_FAILURE);
}

在调试时我看到 shm_open() 的返回值每次都是 0,但我可以在 /dev/shm 中看到这个对象。在执行 ftruncate() 时,它每次都会返回错误“无效参数”。

为什么 fd 每次都是 0,为什么 ftruncate 不起作用? 我该怎么办?

【问题讨论】:

    标签: c linux


    【解决方案1】:

    此语句中的操作顺序很奇怪:

    if((fd = shm_open(shm_name, O_RDWR | O_CREAT, MODE) < 0)) {
    

    您将shm_open(...) &lt; 0 的结果分配给fd,这绝对不是您想要的。

    将比较移到括号外:

    if((fd = shm_open(shm_name, O_RDWR | O_CREAT, MODE)) < 0) {
                                                       ^^^
    

    【讨论】:

    • 非常感谢。有时它是如此简单的解决方案!
    【解决方案2】:

    您也可以先声明 fd,然后将其与 0 进行比较。

        int fd = shm_open(shm_name, O_RDWR | O_CREAT, MODE);
        if (fd < 0){
           perror("\nshm_open() in Caretaker failed");
        }
    

    毕竟它会减少混乱。

    【讨论】: