注册

Linux报 “invalid shared memory segment size” 异常的原因以及解决办法

Linux OS 中的shmget系统调用用于获取共享内存ID。如果调用该系统调用时传递的size参数超出了操作系统允许的最大共享内存限制,就会出现“invalid shared memory segment size”的错误。

这个问题的解决需要修改Linux内核参数来提高共享内存大小限制。下面是具体的步骤:

  1. 判断当前共享内存大小限制
# 查看当前内存参数
$ ipcs -lm
------ Shared Memory Limits --------
max number of segments = 4096
max seg size (kbytes) = 32768
max total shared memory (kbytes) = 8388608
min seg size (bytes) = 1

可以看到当前操作系统支持的最大共享内存为32MB。

  1. 修改内核参数

修改 /etc/sysctl.conf 配置文件,将 kernel.shmmax 的值修改为需要的最大共享内存大小。

# 打开 /etc/sysctl.conf 进行编辑
$ sudo vim /etc/sysctl.conf
# 添加以下行
kernel.shmmax=2147483648
  1. 加载内核参数配置

执行以下命令可以将修改后的内核参数配置加载到操作系统中。

# 加载内核参数配置
$ sudo sysctl -p /etc/sysctl.conf
  1. 修改共享内存大小并获取ID

最后,重新使用 shmget 获取共享内存ID。如果需要分配的大小超出了之前的限制,可以设置更大的值。例如:

#include 
#define SIZE 2097152  // 2MB大小共享内存

int main() {
    key_t key = 1234;
    int shmid;
    char *data;

    // 获取共享内存ID
    if ((shmid = shmget(key, SIZE, 0666 | IPC_CREAT)) == -1) {
        perror("shmget");
        exit(1);
    }

    // 将共享内存连接到当前进程的地址空间
    if ((data = shmat(shmid, NULL, 0)) == (char *) -1) {
        perror("shmat");
        exit(1);
    }

    // 写共享内存
    strcpy(data, "Hello, world!");

    // 解除连接共享内存
    shmdt(data);

    return 0;
}

总之,解决“invalid shared memory segment size”的错误需要三个步骤:查看当前共享内存大小限制,修改内核参数并加载,然后更改使用 shmget 接口创建共享内存时的大小。