Управление общей памятью в C на OSX

Я работаю над университетским заданием, основанным в основном на IPC и общей памяти. Проблема в том, что, будучи полным нубом в C, я с удовольствием тестировал свое приложение (которое, очевидно, использует shmget и shmat) в течение нескольких часов. Как вы, наверное, догадались, я не убирал за собой, и теперь я не могу запустить свое приложение, потому что (я предполагаю) shmget не могу выделить больше ресурсов.

Мой вопрос: как я могу вернуть этот ресурс без перезапуска OSX, и есть ли инструмент с графическим интерфейсом или что-то, что я могу использовать для мониторинга/управления этой общей памятью, которую я создаю?


person Ash    schedule 25.11.2010    source источник


Ответы (2)


Вызовите shmdt ("отключение общей памяти") в сегменте общей памяти в каждый процесс, который содержит ссылку на него. Разделы общей памяти Unix подсчитываются, поэтому, когда последний процесс отсоединяется от них, их можно уничтожить с помощью shmctl(id, IPC_RMID, NULL).

Извне вашего приложения единственный вариант, который я могу придумать прямо сейчас, чтобы очистить ваши сегменты общей памяти:

for (int id=0; id < INT_MAX; id++)
    shmctl(id, IPC_RMID, NULL);

но это ужасно неэффективный кладж. (Я также не уверен, работает ли это; это не работает в Linux, но Linux нарушает стандарт Unix, в то время как MacOS X сертифицирован для него.)

person Fred Foo    schedule 25.11.2010
comment
Это на самом деле очень полезно, но если я еще этого не сделал, могу ли я освободить всю общую память через Терминал или что-то в этом роде? - person Ash; 25.11.2010
comment
Я опубликовал обновление с фрагментом кода, который должен это сделать. У меня нет MacOS X, поэтому я не могу проверить команды, которые делают это за вас. Попробуйте man shmget и т. д. и просмотрите разделы SEE ALSO. - person Fred Foo; 25.11.2010
comment
хорошо, рад, спасибо. Что касается вашего предложения, я прав в своем использовании, когда я вызываю shmdt(shm_id);, где shm_id - это int, который я получаю, когда я первоначально вызывал shmget()? Что, если я разветвил процесс, ссылка на shmget также будет клонирована (так что, если один разветвленный процесс вызывает shmdt(), ОС не уничтожит память из другого?) - person Ash; 25.11.2010
comment
Ваше первое предположение верно. Я не могу найти поведение разных вилок в стандарте Unix; Solaris, по-видимому, передает сегмент дочерним процессам. Я бы посоветовал вам переключиться на mmap с MAP_SHARED (opengroup.org/onlinepubs/ 009695399/functions/mmap.html), если это вообще возможно; этот интерфейс намного проще в использовании. - person Fred Foo; 25.11.2010
comment
Поскольку этот идентификатор для университетского задания, я не думаю, что мне разрешено. Но я буду следить за поведением и видеть, что происходит. - person Ash; 25.11.2010
comment
Кажется, что запуск printf("shmdt returns: %d\n", shmdt(shm_id)); всегда возвращает -1, о чем говорит страница, на которую вы ссылаетесь в своем ответе. В противном случае сегмент общей памяти не должен быть отсоединен, shmdt() должен возвращать -1. Где shm_id = shmget(SHM_KEY, N * sizeof (FILE_entry), IPC_CREAT | 0644); - я что-то не так сделал? - person Ash; 25.11.2010
comment
Вы проверили возвращаемое значение shmget на -1? - person Fred Foo; 25.11.2010
comment
Возвращаемое значение всегда равно -1 (см. выше). Или я вас неправильно понял? - person Ash; 25.11.2010
comment
Для shmget, а не для shmdt. Вы действительно получаете действительные удостоверения личности? - person Fred Foo; 25.11.2010
comment
нет, но я выполняю entries = (FILE_entry *) shmat(shm_id, NULL, 0);, в котором я могу хранить данные. - person Ash; 25.11.2010
comment
Прости, Эш, боюсь, я больше ничем не могу тебе помочь. Пожалуйста, внимательно прочитайте свои справочные страницы, чтобы узнать о поведении MacOS X, опубликуйте новый вопрос или произведите впечатление на своего преподавателя решением на основе mmap. - person Fred Foo; 25.11.2010
comment
IPC_STAT не нужен - shmctl(id, IPC_RMID, NULL); подойдет (именно id, а не shmid_ds определяет сегмент разделяемой памяти для работы). - person caf; 26.11.2010

Возможно, немного поздно, но для этого есть инструменты cmdline. ИПКС и ИПКРМ

взгляните на их справочные страницы.

person wouter    schedule 13.05.2011