2014-07-23 37 views
1

我在linux系統上學習ipc。在我嘗試了幾個使用共享內存的示例程序之後,我發現有一些共享內存部分在我的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 

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

今天我開始計算ter和我發現這些共享內存段消失了。昨天我關閉電腦前,他們還在那裏。我不知道爲什麼。

+0

不錯的問題。你不能真正知道什麼時候不再需要shm,但是也許cron工作應該查看「最後訪問」時間並定期清理? –

+0

[有趣的命令(http://www.commandlinefu.com/commands/view/8916/remove-all-unused-shared-memory-segments-for-current-user) –

+0

喜,@KerrekSB,感謝您的評論。我知道這些shm不再使用。它們是由一些在幾天前執行的實驗程序創建和附加的。有些程序在退出之前沒有調用shmdt,現在它們沒有運行。 – user3693690

回答

0

WEL首先用下面給出的詳細裝備您的代碼:

可以在代碼中使用int shmctl(int shmid, int cmd, struct shmid_ds *buf);如果萬一你的程序失敗或常退出,以除去從系統中共享存儲器段。

但是,您應該查看shmctl手冊頁的IPC_RMID部分。

IPC_RMID標記段被破壞:以下條件man頁面狀態您嘗試刪除共享內存seciton之前必須滿足。 該段只會在最後一個進程分離後才被實際銷燬(即 ,當 shmid_ds的shm_nattch成員爲零時)。來電者必須是所有者或創建者,或者是 privi- 。如果段已被標記爲銷燬,則將設置由IPC_STAT檢索的 關聯數據結構中的shm_perm.mode 字段的(非標準)SHM_DEST標誌。

調用者必須確保段最終被銷燬;否則其出現故障的頁面將保留在 內存 或交換。

另請參閱proc(5)中對/ proc/sys/kernel/shm_rmid_forced的描述。

您可以參考下面的代碼,例如:

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

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

要刪除現有的共享內存段,它能夠更好地使用ipcrm -m <shmid>作爲已經在這個問題的意見告訴。你可以創建一個可以刪除所有段的shell腳本。

相關問題