C++ 无法解释的Linux System V IPC共享内存段标记为要销毁

C++ 无法解释的Linux System V IPC共享内存段标记为要销毁,c++,linux-kernel,virtual-machine,shared-memory,C++,Linux Kernel,Virtual Machine,Shared Memory,我有一个Linux System V IPC共享内存段,它由一个进程填充,由许多其他进程读取。所有进程都以类的形式使用共享内存段的接口,该类负责查找、附加和分离内存段,作为其构造函数/析构函数方法的一部分 这里的问题是,我不时地看到细分市场已经“分裂”。我在这里的意思是,在“ipcs-m-s”输出中,我看到列出了两个部分:一个已经标记为销毁,但仍有一些进程附加到它,另一个似乎获得了所有新的尝试附加到该部分。但是,我从来没有真正要求内核销毁该段。这里发生了什么 另一件需要注意的事情是,不幸的是,这

我有一个Linux System V IPC共享内存段,它由一个进程填充,由许多其他进程读取。所有进程都以类的形式使用共享内存段的接口,该类负责查找、附加和分离内存段,作为其构造函数/析构函数方法的一部分

这里的问题是,我不时地看到细分市场已经“分裂”。我在这里的意思是,在“ipcs-m-s”输出中,我看到列出了两个部分:一个已经标记为销毁,但仍有一些进程附加到它,另一个似乎获得了所有新的尝试附加到该部分。但是,我从来没有真正要求内核销毁该段。这里发生了什么

另一件需要注意的事情是,不幸的是,这个系统正在运行的内存部门严重过量。有1GB的物理内存,没有交换,而/proc/meminfo中提交的_报告的提交内存约为2.5GB。幸运的是,系统进程实际上没有使用这么多内存。。。他们只是要求这样做(据vmstat报告,我仍然有大约660MB的“空闲”内存)。虽然我知道这远非理想,但对于过度投入的记忆,目前我无能为力。但是,在浏览kernel/libc源代码时,除了用户请求之外,我在其中没有看到任何会将共享内存段标记为删除的内容(但可能我错过了隐藏在其中的内容)

以下是共享内存接口类的构造函数供参考:

const char* shm_ftok_pathname = "/usr/bin";
int shm_ftok_proj_id = 21;

// creates a key from a file path so different processes will get same key
key_t m_shm_key = ftok(shm_ftok_pathname, shm_ftok_proj_id);

if ( m_shm_key  == -1 )
{
    fprintf(stderr,"Couldn't get the key for the shared memory\n%s\n",strerror(errno));
    exit ( status );
}

m_shm_id = shmget(m_shm_key, sizeof(shm_data_s), (IPC_CREAT | 0666));

if (m_shm_id < 0) 
{
    fprintf(stderr,"Couldn't get the shared memory ID\nerrno = %s  \n",strerror(errno));
    exit ( status );
}

// get a ptr to shared memory, which is a shared mem struct 
// second arg of 0 says let OS choose shm address
m_shm_data_ptr = (shm_data_s *)shmat(m_shm_id, 0, 0);

if ( (int)m_shm_data_ptr == -1 )
{
    fprintf(stderr,"Couldn't get the shared memory pointer\n");
    exit ( status );
}
const char*shm\u ftok\u pathname=“/usr/bin”;
int shm_ftok_项目id=21;
//从文件路径创建密钥,以便不同进程将获得相同的密钥
key\t m\u shm\u key=ftok(shm\u ftok\u路径名、shm\u ftok\u项目id);
如果(m_shm_key==-1)
{
fprintf(stderr,“无法获取共享内存的密钥\n%s\n”,strerror(errno));
退出(状态);
}
m_shm_id=shmget(m_shm_键,sizeof(shm_数据),(IPC_创建| 0666));
如果(m_shm_id<0)
{
fprintf(stderr,“无法获取共享内存ID\nerrno=%s\n”,strerror(errno));
退出(状态);
}
//获取共享内存的ptr,这是一个共享内存结构
//第二个参数0表示让操作系统选择shm地址
m_shm_data_ptr=(shm_data_s*)shmat(m_shm_id,0,0);
如果((int)m_shm_data_ptr==-1)
{
fprintf(stderr,“无法获取共享内存指针\n”);
退出(状态);
}
以下是我的uname输出:
Linux 2.6.18-5-686#1 SMP Fri Jun 1 00:47:00 UTC 2007 i686 GNU/Linux

我的第一个猜测是,您可能正在某处调用
shmctl(…,IPC#RMID…)


您可以显示共享内存接口类“析构函数”吗?

内核将段标记为删除的唯一原因是显式用户调用。可能是您可以尝试strace/truss(在solaris中)以了解是否有用户调用上述1中提到的函数


Raman Chalotra

我想知道你是否需要担心Linux OOM杀手,因为内存不足?谷歌it…谢谢你的输入,但我不认为我遇到了OOM问题。首先,我看不到任何进程被杀死的证据,我也不希望看到,因为我从来没有真正耗尽内存(即,虽然聚合内存请求确实比可用内存多,因为进程实际上没有使用内存,但有很多可用页面)。即使进程被终止,我也看不出我在共享内存设置中所做的任何事情会如何导致内存“分裂”。+1同意,必须在某个地方调用shmctl(…IPC_RMID…)。这将是有意义的是在描述。。。你确定没有调用析构函数吗?事实上,在第一次附加后调用shmctl(…IPC_RMID…)是很典型的,因此当没有更多引用时,段会自动删除。实际上,删除段的唯一真正原因是该段被标记为删除,并且没有剩余引用。