как удалить сегмент разделяемой памяти после того, как некоторая программа не смогла отсоединиться от нее перед выходом?

Вопрос:

Я изучаю ipc на linux-системе. После того, как я попробовал несколько примеров программ с использованием общей памяти, я нашел раздел разделов общей памяти, ожидающий моей Linux-системы, и их нельзя удалить.

Я перезагружаю машину, и они остаются.

Я пишу программу, пытающуюся удалить их, и это тоже не работает. Потому что система думала, что есть какая-то программа, все еще связанная с этим сегментом разделяемой памяти (см. Столбец nattch).

Кто-нибудь знает, как их удалить. Благодарю.

[[email protected] 17.2UNIXDomainSocket]# ipcs -m

------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status
0x00000000 98304      root       600        393216     2          dest
0x00000000 131073     root       600        393216     2          dest
0x00000000 163842     root       600        393216     2          dest
0x00000000 196611     root       600        393216     2          dest
0x00000000 229380     root       600        393216     2          dest
0x00000000 262149     root       600        393216     2          dest
0x00000000 294918     root       600        393216     2          dest
0x00000000 327687     root       600        393216     2          dest
0x00000000 360456     root       600        393216     2          dest
0x00000000 393225     root       600        393216     2          dest
0x00000000 425994     root       600        393216     2          dest
0x00000000 458763     root       600        393216     2          dest

clearShm.c

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>

int main(int argc, char *argv[])
{
int shmIDArray[]={98304,131073,163842,196611,229380,262149,294918,327687,360456,393225,425994,458763};
for(int i=0; i<sizeof(shmIDArray)/sizeof(int); i++)
{
if(shmctl(shmIDArray[i], IPC_RMID, NULL) < 0)
{
fprintf(stderr, "remove error for shmid=%d: %s\n", shmIDArray[i], strerror(errno));
}else{
printf("delete %d\n", shmIDArray[i]);
}
}
return 0;
}

вывод оболочки для программы выше

[[email protected] 17.2UNIXDomainSocket]# ./clearShm
delete 98304
delete 131073
delete 163842
delete 196611
delete 229380
delete 262149
delete 294918
delete 327687
delete 360456
delete 393225
delete 425994
delete 458763

=============================================

Сегодня я запустил компьютер, и я обнаружил, что сегменты разделяемой памяти исчезли. Они все еще были там, прежде чем я выключил компьютер вчера. и я не знаю почему.

Ответ №1

Сначала Wel оборудуйте свой код с приведенными ниже деталями:

Вы можете использовать int shmctl(int shmid, int cmd, struct shmid_ds *buf); в вашем коде, чтобы удалить сегмент разделяемой памяти из системы, если в случае отказа вашей программы или выхода из нее.

Однако вы должны посмотреть раздел IPC_RMID на странице man shmctl. man страница состояния ниже условия должны быть выполнены, прежде чем пытаться удалить общий seciton памяти:

IPC_RMID Отметьте сегмент, который нужно уничтожить. Сегмент будет фактически уничтожен только после того, как последний процесс отделит его (т.е. Когда член shm_nattch связанной структуры shmid_ds равен нулю). Вызывающий должен быть владельцем или создателем или быть приватизированным. Если сегмент отмечен для уничтожения, то будет установлен флаг (нестандартный) SHM_DEST поля shm_perm.mode в связанной структуре данных, полученной IPC_STAT.

Вызывающий должен обеспечить, чтобы сегмент был уничтожен; в противном случае его страницы, которые были сбойными, останутся в памяти или свопированы.

См. Также описание /proc/sys/kernel/shm_rmid_forced в proc (5).

Вы можете обратиться к нижеприведенному коду, например:

if(-1 == (shmctl(shmid, IPC_STAT, &shmid_ds)))
{
perror("shmctl");
}

if(-1 == (shmctl(shmid, IPC_RMID, &shmid_ds)))
{
perror("shmctl");
}

Чтобы удалить существующие сегменты разделяемой памяти, лучше использовать ipcrm -m <shmid> как уже сказано в комментариях к вопросу. Вы можете создать сценарий оболочки, который может удалить все сегменты.

Оцените статью
TechArks.Ru
Добавить комментарий