【问题标题】:Putting a Struct into Shared Memory将结构放入共享内存
【发布时间】:2016-02-24 19:33:06
【问题描述】:

我创建了两个程序 server.c 和 client.c。我有一个包含年龄的结构。我已经让程序一起工作以读取共享内存并更改共享内存,但这仅在使用结构中的一个变量时才有效。一旦结构中有多个变量,就会出现分段错误。

Server.c

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

typedef struct People
{
    int age;
    int isDone;

} Person;

int main()
{
    Person aaron;
    Person *p_aaron;
    int id;
    int key = 5432;

    p_aaron = &aaron;
    (*p_aaron).age = 19;
    (*p_aaron).isDone = 0;

    if ((id = shmget(key,sizeof(aaron), IPC_CREAT | 0666)) < 0)
    {
        perror("SHMGET");
        exit(1);
    }


    if((p_aaron = shmat(id, NULL, 0)) == (Person *) -1)
    {
        perror("SHMAT");
        exit(1);
    }

    (*p_aaron).age = 19;


    printf("Shared Memory Age: %d\n", (*p_aaron).age);
    *p_aaron = aaron;

    while ((*p_aaron).age == 19)
    {
        sleep(1);
    }

    printf("Shared Memory Age Turned To: %d", (*p_aaron).age);


    return 0;
}

Client.c

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

typedef struct People
{
    int age;

} Person;

int main()
{
    Person aaron;
    Person *p_aaron;
    int id;
    int key = 5432;

    p_aaron = &aaron;

    id = shmget(key,sizeof(aaron), IPC_CREAT | 0644);
    p_aaron = shmat(id, NULL, 0);

    printf("%d", (*p_aaron).age);
    (*p_aaron).age = 21;


    return 0;
}

来自 Server.c 的错误消息

SHMGET: Invalid argument

RUN FINISHED; exit value 1; real time: 0ms; user: 0ms; system: 0ms

【问题讨论】:

  • 符号p_aaron-&gt;age 是有充分理由发明的;使用它而不是(*p_aaron).age
  • 客户端和服务器之间似乎没有任何同步。我不认为共享内存是这样工作的。
  • 您应该让客户端和服务器代码就结构的大小达成一致。这应该在两个程序都使用的标题中定义。其他任何事情都是灾难的根源。

标签: c linux struct shared-memory


【解决方案1】:

您没有显示任何删除共享内存段的代码。

如果您查看 shmget() 的 POSIX 规范,您将看到您报告的 EINVAL 错误可以在以下情况下给出:

[EINVAL]
将创建一个共享内存段,并且 size 的值小于系统规定的最小值或大于系统规定的最大值。
[EINVAL]
不会创建任何共享内存段,并且 key 存在共享内存段,但与其关联的段的大小小于 size。

我想你可能会遇到第二种情况;您正在尝试创建一个比已经存在的更大的共享内存段。

  • 修改您的代码以自行清理(shmdt()shmctl())。
  • 使用ipcrm 删除现有的共享内存段。

另外,正如我在comment 中指出的,您应该确保客户端和服务器程序就共享内存中结构的大小达成一致。其他任何事情都是灾难的根源。您应该将结构定义放入头文件中,并且您的两个程序都应该使用该头文件,并且当您更改头文件的定义时都应该重新编译。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多