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

时间:2014-12-08 18:10:13

标签: c linux segmentation-fault ipc shared-memory

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

这很好用,但过了一会儿(通常是几个小时),检索数据的程序会因为段错而崩溃。我使用gdb将seg故障定位到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                   

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

提前谢谢你。

1 个答案:

答案 0 :(得分:2)

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

如果您仍然多次附加内存段,那么每次都必须通过shmdt() de 转发它,否则,是的,你最终会填满进程的整个地址空间。

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