使用共享内存以及如何正确取消分配带有IPC_RMID的空间 [英] Using shared memory and how to correctly unallocate a space with IPC_RMID

查看:287
本文介绍了使用共享内存以及如何正确取消分配带有IPC_RMID的空间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Linux机器上运行了2个应用程序,分别是服务器和客户端.我正在使用的服务器和客户端示例来自 戴夫马歇尔示例.

I have 2 applications running on my linux box, a server and a client. My server and client examples I am working with is from Dave Marshalls examples.

一切正常,但是当我在后台流程中尝试此操作并且想要扩展我的原始段(也许由于将来的应用程序升级)时,我要么必须更改密钥,要么以某种方式通过shmctl(shmid, IPC_RMID, 0)调用在我的应用中.由于我的应用程序无法正常退出,并且分配后无法在开始时设置此权限(因为一旦将其标记为删除,其他任何应用程序都将无法使用此共享的内存空间),因此我无法清理此空间.

Everything works well, but when I try this in my background process and I want to extend my original segment (perhaps due to an application upgrade in the future) I either have to change my key or somehow pass the shmctl(shmid, IPC_RMID, 0) call in my app. Since my app cannot exit graciously and I cannot set this right at the beginning after allocation (since no other app will be able to use this shared mem space once it has been marked for deletion) I have no way of cleaning this space up.

到目前为止,我想出的最好的办法是在我的旧部分中shmget,检查它是否存在,清除它是否存在,然后将其分配给较高的值.看起来像这样:

The best I have come up with so far is to shmget my old section, check if it exists, clear it if it does then allocate it to a high value. This would look like:

void init_shared_mem(void)
{
    int shmid;
    key_t key = 0x1235; //key to be passed to shmget()
    int oldSize = 27;
    int newSize = 28;
    char * shm;

    //check to see if an allocation exists
    if ((shmid = shmget(key, oldSize, IPC_CREAT | 0666)) < 0)
    {
        perror("shmget: shmget failed");
    }
    //unallocate it if it does
    else if (shmctl(shmid , IPC_RMID , 0) == -1)
    {
        perror("shmid");
    }


    //reallocate new section
    if ((shmid = shmget(key, newSize, IPC_CREAT | 0666)) < 0)
    {
        perror("shmget: shmget failed");
        exit(1);
    }

    if ((shm = shmat(shmid, NULL, 0)) == (char *) -1)
    {
        perror("shmat");
        exit(1);
    }
}

其他类似的问题似乎没有涉及或提出来.是否有更好的方法可以解决我遗失的问题,或者我可以简单地将其重新分配给更高的值,而不是清除它?

Other SO questions either don't seem to touch on this or bring it up as a possible concern. Is there a better way to do this that I am missing or perhaps I can simply reallocate it to a higher value instead of clearing it?

推荐答案

您没有说要在哪个操作系统上运行.如果您使用的是 Linux ,则其他以特殊方式配置的操作系统完成IPC_RMID之后,您很可能可以附加附件,只要仍然附加了附件,但请记住,此行为是不可移植的(这里是一个较旧的

You don't say which operating system you are running on. If you're on Linux, OpenBSD 5.1 or later or other operating systems configured a particular way you may well be able to attach after having done IPC_RMID so long as something is still attached to it but bear in mind this behaviour is not portable (here's an older examination of IPC_RMID behaviour on different OSes). Without this behaviour it's going to be difficult to avoid stale segments being left behind if your program crashes (aka "doesn't exit graciously") when it's the last thing attached to the segment.

我还应该注意,您的问题听起来与稳健过程的选项中讨论过的问题相似在UNIX套接字常见问题论坛上进行清理,其中包括以下建议:使用Linux的IPC_RMID行为,对父进程进行监视以检查进程是否死亡并进行清理.

I should also note that your question sounds similar to the problem discussed over in Options for robust process cleanup over on the UNIX Socket FAQ forum where suggestions included: use Linux's IPC_RMID behaviour, have a monitoring parent process check for process death and do cleanup.

这篇关于使用共享内存以及如何正确取消分配带有IPC_RMID的空间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆