Вопрос:
Я изучаю 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: %sn», shmIDArray[i], strerror(errno)); }else{ printf(«delete %dn», 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> как уже сказано в комментариях к вопросу. Вы можете создать сценарий оболочки, который может удалить все сегменты.