Удалите сегменты общей памяти unix с помощью программы на C ++ - PullRequest
1 голос
/ 02 марта 2012

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

ipcs -m | awk '{ print $2 }' | xargs ipcrm -m

Но я пытаюсь сделать это с помощью C ++, чтобы создать сборщик мусора с общей памятью.

Идея состоит в том, чтобы удалить сегменты разделяемой памяти, которые не привязаны ни к какому процессу (nattach == 0) или к состоянию == NULL

Ответы [ 4 ]

5 голосов
/ 11 апреля 2012

У меня наконец есть ответ на мой собственный вопрос. Это можно сделать с помощью флагов shmctl. shmctl(0,SHM_INFO,&shm_info); дает количество сегментов, присутствующих в данный момент.

shmctl(i , SHM_STAT , &shm_segment) дает идентификатор сегмента

к нему также можно получить доступ shm_segment.shm_id

#include <sys/shm.h>     

int delete_segment(int seg_id){
    if ((shmctl(seg_id,IPC_RMID,0))==-1){
    std::cout<<" ERROR(C++)with shmctl(IPC_RMID): "<<strerror(errno)<<std::endl;
    return -1;
    }else//on success
        return 0;
}

void clean_segments(){

    struct shmid_ds shm_info;
    struct shmid_ds shm_segment;
    int max_id = shmctl(0,SHM_INFO,&shm_info);
    if (max_id>=0){
        for (int i=0;i<=max_id;++i) {
                int shm_id = shmctl(i , SHM_STAT , &shm_segment);
                if (shm_id<=0)
                    continue;
                else if (shm_segment.shm_nattch==0){
                    delete_segment(shm_id);
                }
        }
    }
    return result;
}
2 голосов
/ 02 марта 2012

Согласно исходному коду из ipcrm он вызывает shmctl.

shmctl(id, IPC_RMID, NULL)
1 голос
/ 02 марта 2012

Я бы предложил выполнить strace ipcrm -m <your-arguments> и посмотреть, какие системные вызовы он выполняет. В большинстве случаев этого должно быть достаточно (по крайней мере, оно укажет вам правильное направление), если нет - посмотрите на исходный код ipcrm . Я уверен, что вам не нужны никакие специальные привилегии (в моей системе ipcrm не установлены биты SUID или SGID).

0 голосов
/ 05 февраля 2017

В приведенном ниже коде используйте I:

    void clean_segments(int startId, int endId) {
    for (int i=startId; i<=endId; ++i) {
        struct shmid_ds shm_segment;
        int shm_id = shmctl(i, SHM_STAT, &shm_segment);
        delete_segment(shm_id);
        printf("Segment %d has been deleted\n", shm_id);
    }}

clean_segments (1146894, 6357160); // пример использования кода выше

...