共享内存错误:在CentOS6.8中shmat返回NULL,errno(22:无效参数)

时间:2016-09-26 16:47:36

标签: c linux ipc shared-memory

这是我等待共享内存的两个文件,一个是共享内存的写入数据,另一个是共享内存和printf数据的读取数据;但是有一些错误。

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返回NULL,errno(22:无效参数)

所以我不知道发生了什么?我尝试解决它,例如使用ipcs -m,但没有出现shmid。    我cat / proc / 7116 / maps:     &#34;没有这样的文件或目录&#34;

谁能告诉我发生了什么?如何在CentOS6.6中找到shmid

uname -r: 
2.6.32-504.12.2.el6.x86_64

我也使用cat / proc / sysvipc / shm | grep 65537,但没有出现shmid。    运气不好!

如果您知道,请告诉我如何解决问题,谢谢!

2 个答案:

答案 0 :(得分:0)

我已下载并运行您的程序,但无法重现您的[冲突]结果。

要列出活动的shm段,请使用ipcs命令。如果您需要删除您创建的那个,可以使用ipcrm命令。

我可以想到两件事情可能对你来说是一个问题,但是因为你说你成功地运行了第一个而我对它们进行了折扣时间。

段上的权限,因为您第一次创建错误。 ipcs应该显示这一点。

当你调试你的编写器程序时,它可能做错了什么。这可以通过ipcs看到。如果出现错误,您可以使用ipcrm手动删除细分,然后重新尝试您的程序。

另一种可能性是您的密钥与另一个程序创建的其他部分冲突。这不太可能有两个原因。

你的钥匙很可能是独一无二的。也可以使用ipcs

进行检查

现在大多数程序都使用0x00000000的密钥,这是&#34;私有&#34;模式。这是在程序执行fork执行execvp时完成的。孩子只是调用一些功能(例如child_worker)。父母和孩子使用&#34;私人&#34;来回传递数据。分割。由于该细分受众群是私密的,因此您不必担心拥有唯一的密钥值。

因为你有两个独立的程序,使用该模式适用于你的用例。您需要一个非零键值,以便您的片段持久从一个程序调用到下一个程序。

为简单起见,我将两个程序合并为一个程序。我还添加了一个删除shm段的选项。

注意:我只做化妆品清理。我做了修复任何错误。所以,这只是我在我的系统上测试的一个FYI:

#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;
}

答案 1 :(得分: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.