Using shared memory and how to correctly unallocate a space with IPC_RMID

删除回忆录丶 提交于 2019-12-04 06:26:18

问题


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.

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.

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?


回答1:


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.

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.



来源:https://stackoverflow.com/questions/42478647/using-shared-memory-and-how-to-correctly-unallocate-a-space-with-ipc-rmid

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!