使用C++程序删除unix共享内存段

Delete unix shared memory segments using a C++ program

本文关键字:共享 内存 unix 删除 C++ 程序 使用      更新时间:2023-10-16

我正在尝试编写一个C++程序来删除共享内存段。我知道可以使用从cmd提示符完成

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

但是我正在尝试使用C++来实现这一点,以便创建一个共享内存垃圾收集器。

其想法是删除未附加到任何进程(nattach==0)或状态==NULL 的共享内存段

我终于有了自己问题的答案。这可以使用shmctl标志来完成。shmctl(0,SHM_INFO,&shm_info);给出了当前存在的分段数。

shmctl(i , SHM_STAT , &shm_segment)给出段id

它也可以由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;
}

根据ipcrm的源代码,它调用shmctl

shmctl(id, IPC_RMID, NULL)

我建议执行strace ipcrm -m <your-arguments>,看看它执行什么系统调用。在的大多数情况下,应该是足够的(至少它会为您指明正确的方向),如果不是,请查看ipcrm的源代码。我确信您不需要任何特殊权限(我的系统上的ipcrm没有设置SUID或SGID位)。

下面的代码使用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 deletedn", shm_id);
    }}

clean_segments(1146894、6357160);//使用上的代码的示例