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

Linux 2.6下模拟memfd_create的更优替代方案技术咨询

针对Linux 2.6替代memfd_create的更优方案

刚好之前维护老Linux 2.6项目时碰到过一模一样的场景,来给你分享几个更优的替代方案,解决你对mkstemp+unlink方式的不满:

1. 优先推荐:shm_open + shm_unlink组合

Linux 2.6已经完全支持POSIX共享内存API的shm_open(内核2.4+就引入了),它创建的文件默认位于/dev/shm——这是一个基于内存的tmpfs文件系统,完全没有磁盘IO开销,完美匹配你避免物理文件开销的需求。

实现逻辑:

  • 用shm_open创建一个带随机后缀的临时共享内存对象(避免命名冲突)
  • 立即调用shm_unlink删除该对象的文件系统入口,这样即使进程意外崩溃,内核也会自动回收这块内存(不会像普通文件那样残留磁盘空间)
  • 通过ftruncate设置内存区域的大小,再用mmap映射到进程地址空间

示例代码:

#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>

int main() {
    // 生成带随机后缀的共享内存名称,避免冲突
    char shm_name[] = "/tmp_shm_obj_XXXXXX";
    int fd = shm_open(shm_name, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
    if (fd == -1) {
        perror("shm_open failed");
        exit(EXIT_FAILURE);
    }

    // 立即unlink,移除文件系统中的入口
    if (shm_unlink(shm_name) == -1) {
        perror("shm_unlink failed");
        close(fd);
        exit(EXIT_FAILURE);
    }

    // 设置共享内存区域的大小(按需调整)
    off_t size = 4 * 1024 * 1024; // 4MB
    if (ftruncate(fd, size) == -1) {
        perror("ftruncate failed");
        close(fd);
        exit(EXIT_FAILURE);
    }

    // 映射到进程地址空间
    void *addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (addr == MAP_FAILED) {
        perror("mmap failed");
        close(fd);
        exit(EXIT_FAILURE);
    }

    // 这里可以使用映射后的内存区域...

    // 清理资源
    munmap(addr, size);
    close(fd);
    return EXIT_SUCCESS;
}

这个方案的优势:

  • 完全基于内存,无磁盘IO开销,比mkstemp+unlink(依赖/tmp是否为tmpfs)更可靠
  • API更贴合“匿名内存对象”的需求,shm_unlink后内核自动回收机制更稳定
  • 保留了文件描述符,满足你需要传递fd给mmap或其他操作的场景

2. 极简方案:MAP_ANONYMOUS直接映射(无需fd时使用)

如果你不需要保留文件描述符,只是需要一块匿名的内存区域,那Linux 2.6支持的MAP_ANONYMOUS(或MAP_ANON别名)是最直接的选择——连文件都不用创建,直接调用mmap即可:

void *addr = mmap(NULL, 4 * 1024 * 1024, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);

注意:这个方案只适用于不需要操作fd的场景(比如不需要传递给其他进程、不需要调整内存大小等),如果你的业务逻辑必须依赖fd,那就还是用第一个方案。

3. 备选方案:手动挂载tmpfs(不推荐)

如果因为某些限制无法使用shm_open,可以手动挂载一个tmpfs到临时目录,然后在里面用mkstemp创建文件——这样文件也会存在内存中,无磁盘开销。但这个方案需要root权限(或提前在/etc/fstab配置),操作繁琐,不如前两个方案简洁,所以一般不推荐。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 07:29:31