2016-09-26 486 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. 
相关问题