我们知道,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
它创建了一个 shm,在它的第一个地址写入 (int) 10,然后退出。然后输入
./client <shmid>
检查附加到创建的 shm 的 shm 段,打印第一个 int,然后退出。
请注意,我们使用 shmat 和 shmdt 连接到 shm 或从 shm 断开连接,并使用 shmget 创建 shm。
要销毁 shm,我们必须使用 shmctl 手动完成。
结论:
shm 在 Unix 中不作为引用计数进行管理,至少对于 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;
}
最佳答案
它不是纯粹的引用计数。根据 shmctl(2):
这意味着:IPC_RMID
不会立即删除,而只会在下次引用计数降至零后才会删除。
这使您可以使用相同的工具实现多个目标:
RMID
。然后只要服务器在这里,客户端就可以连接。如果服务器出现故障,客户端应该断开连接并且资源由操作系统清理。 关于unix - Unix 共享内存的管理,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9963072/