在 C 中使用 shmat 命令的共享内存出现“无法分配内存”问题

min*_*nae 2 c linux ipc shared-memory segmentation-fault

我有两个 C 程序需要相互通信。我在一个程序中使用 shmget(key, 27, IPC_CREAT | 0666) 将一个变量存储在共享内存中。我每 1 秒更新一次这个变量。在另一个程序中,我使用 shmget(key, 27, 0666) 每 1 秒访问一次它。

这非常有效,但一段时间后(通常是几个小时),检索数据的程序会因段错误而崩溃。我使用 gdb 将段错误查明到 shmget(key, 27, 0666) 行。返回的错误代码为:

ENOMEM 无法为描述符或页表分配内存。

当我使用 ipcs -m 从命令提示符检查共享内存段时,我当前看到以下内容:

------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status      
0x00000000 65536      root       600        393216     2          dest         
0x00000000 98305      root       600        393216     2          dest         
0x00000000 131074     root       600        393216     2          dest         
0x00000000 163843     root       600        393216     2          dest         
0x00000000 196612     root       600        393216     2          dest         
0x00000000 229381     root       600        393216     2          dest         
0x00000000 262150     root       600        393216     2          dest         
0x00000000 294919     root       600        393216     2          dest         
0x00000000 327688     root       600        393216     2          dest         
0x00000000 589833     root       600        393216     2          dest         
0x00000000 655370     root       600        393216     2          dest         
0x00000000 524299     root       600        393216     2          dest         
0x00000000 688140     root       666        27         0                       
0x0008aa53 720909     root       666        27         31950                   
0x0006f855 753678     root       666        27         33564                   
Run Code Online (Sandbox Code Playgroud)

在我看来,我使用的共享内存达到某种最大值时出现问题?但我不知道该怎么办,而且我通过谷歌搜索找到了宝贵的信息。有什么想法吗?该程序需要一次运行至少 24 小时(如果不是更长时间的话)。

先感谢您。

Joh*_*ger 5

您似乎误解了如何使用 Sys V 共享内存段。您不需要shmget()在同一进程中对同一共享内存段执行多次。您应该通过 获取段 ID shmget(),通过 将其附加到您的内存空间shmat(),然后根据需要多次读取和/或写入它。修改对于附加同一共享内存段的其他进程来说是可见的。

如果您确实多次附加内存段,那么您必须确保每次都通过 分离它shmdt()否则,是的,您最终将填满进程的整个地址空间。

此外,要正确使用共享内存,还需要某种同步机制。为此,Sys V 共享内存段的自然补充是 Sys V 信号量。您可以使用它来防止一个进程在另一个进程写入相同数据时读取数据。