2016-09-26 204 views
0

這是我等待兩個文件共享內存,一個是寫入數據共享內存,另一個是從共享內存和printf數據讀取數據;但有一些錯誤。共享內存錯誤:在CentOS6.8中,shmat返回NULL,errno(22:無效參數)

shm_w.c

#include <stdio.h> 

#include <sys/shm.h> 

#include <string.h> 

#define MAX_MEM 4096 




int main() 
{ 

    int shmid; 
    int ret; 
    void* mem; 

    shmid=shmget(0x12367,MAX_MEM,IPC_CREAT | 0666); 
    printf("shmid is = %d,pid=%d\n",shmid,getpid()); 
    mem=shmat(shmid,(const void*)0,0); 
    if((int)mem==-1) 
    { 
      printf("attach faile.\n"); 
    } 

    strcpy((char*)mem,"Hello,this is test memory.\n"); 

    ret=shmdt(mem); 

return 0; 

} 

shm_r.c

#include <errno.h> 

#include <stdio.h> 

#include <sys/shm.h> 

#include <string.h> 

#define MAX_MEM 4096 



int main() 

{ 

     int shmid; 
     int ret; 
     void* mem; 

     shmid=shmget(0x12367,MAX_MEM,0); 
     mem=shmat(shmid,(const void*)0,0); 
     //printf("%s\n",(char*)mem); 
     if(mem==(void*)-1) 
     { 
      fprintf(stderr,"shmat return NULL ,errno(%d:%s)\n",errno,strerror(errno)); 
      return 2; 
     } 
     printf("%s\n",(char*)mem); 

     shmdt(mem); 

return 0; 



} 

當我在CentOS6.8編譯會把兩個.c文件,在第一時間就可以了。

不幸的是,從現在開始,我符文she_w.c是正確太:

的shmid是= 65537,PID = 7116。

但是當我運行shm_r.c,它的出現錯誤:


shmat return NULL ,errno(22:Invalid argument)


,所以我不知道發生什麼事了嗎?我試圖解決它,例如使用ipcs -m,但不出現shmid。 而我cat/proc/7116/maps: 「沒有這樣的文件或目錄」

誰能告訴我發生了什麼?我怎樣才能在CentOS6.6上找到shmid

uname -r: 
2.6.32-504.12.2.el6.x86_64 

我也用cat/proc/sysvipc/shm | grep 65537,但不出現shmid。 不幸運!

請告訴我如何解決問題,如果您知道,謝謝!

+0

'(常量無效*)0' - 使用'NULL'宏來得到一個_NULL指針constant_。 – Olaf

+1

你是一個接一個地運行這兩個程序嗎?當第一個程序在另一個程序啓動之前分離內存段時,您會認爲會發生什麼?您需要等待另一個程序運行,然後才能分離該段。 –

+0

「你是否一個接一個地運行這兩個程序?當第一個程序在另一個程序啓動之前分離內存段時,你會認爲會發生什麼?在分離該段之前,需要等待另一個程序運行。 「爲什麼在讀取程序後必須分離並且不能在寫入程序中分離?我的意思是寫程序寫數據結束,它可以分離,不知爲什麼當寫程序完成時可以使用分離。如果我在寫入程序中使用detach,共享內存將被釋放,所以讀取程序不能讀取數據? – Marcos

回答

0

我已經下載並運行您的程序,無法重現您的[衝突]結果。

要列出活動的shm段,請使用ipcs命令。如果您需要刪除您創建的那個,則可以使用ipcrm命令。

有兩件事情我可以認爲的可能是你的問題,但我貼現他們,因爲你說你成功運行的第一時間。

段上的權限,因爲您第一次創建該段的權限不正確。 ipcs應該顯示這一點。

當您調試編寫程序時,它可能做了一些不正確的事情。這可以通過ipcs來看。如果發生錯誤,您可以用ipcrm手動刪除該段,然後再次嘗試您的程序。

另一種可能性是您的密鑰與另一個程序創建的其他段相沖突。這不太可能有兩個原因。

你的關鍵是,可能都是獨一無二的。這也可以使用ipcs

現在大多數程序使用0x00000000這是「私人」模式的密鑰。這是在程序執行fork時完成的,但是不是執行execvp。孩子只需要調用一些功能(例如child_worker)。父母和孩子使用「私人」細分來回傳遞數據。由於該細分市場是私密的,因此您不必擔心擁有唯一的關鍵值。

因爲你有兩個單獨的程序,使用該模式將而不是工作你的用例。你需要一個非零的鍵值,這樣你的分段將從一個程序調用到下一個持續


爲了簡單起見,我將兩個程序組合成一個程序。我還添加了一個選項來刪除shm段。

注:我只做了美容清理。我做了而不是修復了任何錯誤。所以,這只是一個僅供參考的是我在我的系統上測試:

#include <stdio.h> 
#include <sys/shm.h> 
#include <string.h> 
#include <errno.h> 
#include <stdlib.h> 
#include <unistd.h> 

#define MAX_MEM 4096 
#define XID  0x12367 

int opt_cmd; 

void 
writer(void) 
{ 
    int shmid; 
    void *mem; 

    shmid = shmget(XID,MAX_MEM,IPC_CREAT | 0666); 
    printf("shmid is = %d,pid=%d\n",shmid,getpid()); 
    mem = shmat(shmid,NULL,0); 
    if (mem == (void *) -1) { 
     printf("attach faile.\n"); 
    } 

    strcpy((char *) mem,"Hello,this is test memory.\n"); 

    shmdt(mem); 
} 

void 
reader(void) 
{ 
    int shmid; 
    void *mem; 

    shmid = shmget(XID,MAX_MEM,0); 
    mem = shmat(shmid,NULL,0); 

    // printf("%s\n",(char*)mem); 
    if (mem == (void *) -1) { 
     fprintf(stderr,"shmat return NULL ,errno(%d:%s)\n", 
      errno,strerror(errno)); 
     exit(2); 
    } 

    printf("%s\n",(char *) mem); 

    shmdt(mem); 
} 

void 
clean(void) 
{ 
    int shmid; 

    shmid = shmget(XID,MAX_MEM,0); 
    shmctl(shmid,IPC_RMID,NULL); 
} 

// main -- main program 
int 
main(int argc,char **argv) 
{ 
    char *cp; 

    --argc; 
    ++argv; 

    for (; argc > 0; --argc, ++argv) { 
     cp = *argv; 
     if (*cp != '-') 
      break; 

     switch (cp[1]) { 
     case 'd': 
     case 'w': 
     case 'r': 
      opt_cmd = cp[1]; 
      break; 

     default: 
      break; 
     } 
    } 

    switch (opt_cmd) { 
    case 'w': 
     writer(); 
     break; 

    case 'd': 
     clean(); 
     break; 

    default: 
     reader(); 
     break; 
    } 

    return 0; 
} 
0

對於使用shmget的()調用,就必須包括<sys/ipc.h>

shm_w.c

#include <stdio.h> 
#include <sys/types.h> 
#include <unistd.h> 
#include <sys/ipc.h> 
#include <sys/shm.h> 
#include <string.h> 

#define MAX_MEM 4096 

int main() 
{ 

    int shmid; 
    int ret; 
    void* mem; 

    shmid=shmget(0x12367,MAX_MEM,IPC_CREAT | 0666); 
    printf("shmid is = %d,pid=%d\n",shmid,getpid()); 
    mem=shmat(shmid,(const void*)0,0); 
    if(mem==(void *) -1) 
    { 
      printf("attach faile.\n"); 
    } 

    strcpy((char*)mem,"Hello,this is test memory.\n"); 

    ret=shmdt(mem); 

    return 0; 

} 

shm_r.c

#include <stdio.h> 
#include <sys/types.h> 
#include <unistd.h> 
#include <sys/ipc.h> 
#include <sys/shm.h> 
#include <string.h> 
#include <errno.h> 

#define MAX_MEM 4096 

int main() 

{ 

     int shmid; 
     int ret; 
     void* mem; 

     shmid=shmget(0x12367,MAX_MEM,0); 
     mem=shmat(shmid,(const void*)0,0); 
     //printf("%s\n",(char*)mem); 
     if(mem==(void *) -1) 
     { 
      fprintf(stderr,"shmat return NULL ,errno(%d:%s)\n",errno,strerror(errno)); 
      return 2; 
     } 
     printf("%s\n",(char*)mem); 

      shmdt(mem); 

    return 0; 
    } 

    $ gcc shm_w.c -o shm_w 
    $ gcc shm_r.c -o shm_r 
    $ ./shm_w 
    shmid is = 2293774,pid=5779 
    $ ./shm_r 
    Hello,this is test memory. 

    $ ./shm_r 
    Hello,this is test memory. 

    $ ./shm_r 
    Hello,this is test memory. 
相關問題