Unix共享内存的管理

时间:2012-04-01 08:43:38

标签: unix shared-memory

我们知道,Windows中的共享内存是通过系统页面文件支持的内存映射文件实现的,并且始终以引用计数方式进行管理(http://msdn.microsoft.com/en-us/library/windows /desktop/aa366537(v=vs.85).aspx)。

我想知道Unix是否以类似的方式做到了。有人(http://stackoverflow.com/q/4278391/939142)说Unix也以引用计数方式管理shm。我在Mac OS X上尝试了一个实验,发现事实并非如此。

使用最后提供的代码,编译两个程序:host和client。型

./host 

创建一个shm,在其第一个地址写入(int)10,然后退出。然后输入

./client <shmid>

检查shm段,它附加到创建的shm,打印第一个int,然后退出。

请注意,我们使用shmat和shmdt来连接/断开shm,并使用shmget来创建shm。

要销毁shm,我们必须使用shmctl手动完成。

结论: 在Unix中,shm不作为引用计数进行管理,至少对于Mac OS X

/************************** host.c ****************************/

#include <stdio.h>
#include <sys/shm.h>
#include <mach/vm_param.h>
#include <assert.h>

int
main(int argc, char** argv)
{
int value = 10;
int id;
void* ptr;
    /* create a new shm */
id = shmget(IPC_PRIVATE, PAGE_SIZE, IPC_CREAT | 0666);
assert(id != -1);
    /* attach to the new shm */
ptr = shmat(id, (const void*) NULL, 0);
assert((int*) ptr != -1);
    /* print the id so that client can use */
printf("shm id = %ld\n", id);
printf("address of id = %ld, length = %ld\n", ptr, PAGE_SIZE);
((int*) ptr)[0] = value;
printf("value at address %ld = %ld\n", ptr, *(int*) ptr);
/* detach from the shm and exit */
    shmdt((const void*) ptr);
return 0;
}


/************************** host.c ****************************/

#include <stdio.h>
#include <stdlib.h>
#include <sys/shm.h>
#include "assert.h"
#include <mach/vm_param.h>

int
main(int argc, char** argv)
{
void* ptr;
int id = atoi(argv[1]);
assert(id != -1);
    /* attach to the shm */
ptr = shmat(id, NULL, 0);
assert(ptr != -1);
printf("value at ptr = %ld = %ld\n", ptr, *(int*) ptr);
shmdt((const void*) ptr);
return 0;
}

1 个答案:

答案 0 :(得分:2)

它不是引用计数。根据shmctl(2):

  

IPC_RMID :标记要销毁的细分受众群。该细分受众群只会                    实际上在最后一个进程分离后被销毁                    (即,当相关结构的shm_nattch成员时                    shmid_ds为零)。来电者必须是所有者或创作者,

这意味着:IPC_RMID不会立即删除,但只有在下次引用计数降至零之后才会删除。

这允许您使用相同的工具实现多个目标:

  • 服务器创建,附加并立即设置RMID的服务器/客户端方法。然后只要服务器在这里,客户端就可以连接。如果服务器出现故障,客户端应断开连接,操作系统将清理资源。

  • 或“消息”方法:有人写一条消息,将其固定到已知位置。之后,其他人可以来,寻找消息并采取相应行动。这就是你所做的。当然,这种方法对资源垃圾更加开放。但是有一些用例。