Мы знаем, что общая память в 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, и 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;
}