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

发布于 2024-08-07 18:24:48 字数 1517 浏览 1 评论 0原文

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

这里的问题是,我时不时地看到该段已“分裂”。我在这里的意思是,在“ipcs -m -s”输出中,我看到列出了两个段:一个已被标记为销毁,但仍然附加了一些进程,第二个似乎是获取附加到该段的所有新尝试。但是,我实际上从未要求内核销毁该段。这里发生了什么事?

另一件需要注意的事情是,不幸的是,运行该系统的内存部门严重过度使用。有 1 GB 物理内存,无交换区,/proc/meminfo 中的 Commied_AS 报告大约 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 );
}

这是我的 uname 输出: Linux 2.6.18-5-686 #1 SMP 6 月 1 日星期五 00:47:00 UTC 2007 i686 GNU/Linux

I have a Linux System V IPC shared memory segment that is populated by one process and read by many others. All the processes use interface to the shared memory segment in the form of a class which takes care of looking up, attaching, and detaching to the segment as part of its constructor/destructor methods.

The problem here is that from time to time I'm seeing that the segment has "split". What I mean here is that looking in the "ipcs -m -s" output I see that I've got two segments listed: one which has been marked for destruction but still has some processes attached to it, and a second which appears to get all new attempts to attach to the segment. However, I'm never actually asking the kernel to destroy the segment. What's happening here?!

One other thing to note is that unfortunately the system this is running on is seriously overcommited in the memory department. There is 1 GB of physical memory, no swap, and the Committed_AS in /proc/meminfo is reporting about 2.5GB of commited memory. Fortunately the system processes are not actually using this much memory... they're just asking for it (I still have about 660MB "free" memory as reported by vmstat). While I know this is far from ideal, for the time being there is nothing I can do about the overcommitted memory. However, browsing the kernel/libc source I don't see anything in there that would mark a shared memory segment for deletion for any reason other than a user request (but perhaps I've missed it hidden in there somewhere).

For reference here's the shared memory interface class' constructor:

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 );
}

And here's my uname output:
Linux 2.6.18-5-686 #1 SMP Fri Jun 1 00:47:00 UTC 2007 i686 GNU/Linux

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

凯凯我们等你回来 2024-08-14 18:24:48

我的第一个猜测是您可能正在某处调用 shmctl(..., IPC_RMID, ...)

你能展示共享内存接口类的析构函数吗?

My first guess is that you probably are calling shmctl(..., IPC_RMID, ...) somewhere.

Can you show the shared memory interface class' destructor?

各空 2024-08-14 18:24:48

内核将段标记为删除的唯一原因是显式用户调用。也许您可以尝试 strace/truss(在Solaris 中)以查明是否有用户调用上述函数,如上面 1 中提到的。

拉曼·查洛特拉

The only reason for kernel to mark the segment for deletion is the explicit user call.May be you can give a try to strace/truss(in solaris) to find out if there is a user call to the said function, mentioned in 1 above.

Raman Chalotra

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文