2012-03-01 74 views
1

我正在嘗試編寫一個C++程序來刪除共享內存段。我知道它可以從命令提示符使用使用C++程序刪除unix共享內存段

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

做,但我想用C++,這樣我創建共享內存垃圾收集器做到這一點。

的想法是刪除那些不依附於任何處理(NATTACH == 0)或狀態== NULL

+1

您是否嘗試過從C執行命令++? – 2012-03-01 20:05:58

+0

我認爲如果你想親自去做,你將不得不獲得內核模式特權。您可能仍然使用現有的ABI或API(如果有的話),這可能會更容易:) – Geoffroy 2012-03-01 20:08:15

+0

我想分析此代碼的輸出並檢查nattach == 0,然後將參數傳遞給ipcrm'ipcs -m | awk'{print $ 2}'' – venuktan 2012-03-01 20:14:33

回答

5

我終於對自己的問題有了答案。它可以使用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; 
} 
1

我建議執行strace ipcrm -m <your-arguments>,看看系統調用它執行的共享內存段。在大多數情況下應該是足夠的(至少它會指向你在正確的方向),如果不是 - 請看ipcrm的源代碼。我很肯定你不需要任何特殊的權限(我的系統上的ipcrm沒有設置SUID或SGID位)。

2

根據ipcrmsource code,它調用shmctl

shmctl(id, IPC_RMID, NULL) 
+0

'源代碼'鏈接中斷 – 2012-03-01 23:21:53

+0

@Nasgul,我修復了鏈接,謝謝。 – kamae 2012-03-01 23:30:32

+0

是的,我知道'shmctl(id,IPC_RMID,NULL)',但它只適用於你有段ID。我需要能夠獲得所有當前段ID的列表,檢查是否有任何附加到它的進程並檢查它們是否處於活動狀態並刪除非活動的一次 – venuktan 2012-03-03 04:02:41

0

下面的代碼使用訪問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); //示例使用上面的代碼