如何在两个进程之间共享链表?

时间:2010-02-18 15:42:35

标签: c linux ipc linked-list

我有两个进程,我想在它们之间共享一个链表。其中一个 进程只是要读取列表,而其他进程将修改 列表(添加/删除条目)。你能告诉我如何实现它吗?


让我向其添加更多细节,语言为C,平台为Linux。 似乎共享内存是一种方法,但我不知道如何实现它。

如果任何人能告诉我实现它的方式,那么对我来说将会有很大的帮助。

我有一个想法,如下所述: 我可以做这样的事情,我创建一个节点大小的共享内存段。然后我简单地处理malloc?我的意思是我将在shmget(key,SHMSZ,IPC_CREAT | 0666)的帮助下创建共享内存,其中SHMSZ将具有struct node的大小。所以我只分享两个进程之间的列表。列表中的第一个条目将包含除链接条目之外的所有值0,链接条目将指向列表中的下一个条目,并且该条目是在malloc的帮助下创建的,因为在我的应用程序中,因为其他进程仅在一个进程要添加时才会读取/删除列表中的条目。

我收到一条回复,告诉我我不能使用malloc。我不知道为什么我不能 使用malloc。你能告诉我为什么我不能使用malloc吗?

以下是我上述目的的代码,我一直在尝试但是会出现分段错误。

struct node
{
    int val;
    struct node* next;
};

void append(struct node *q,int val);
main()
{

    key_t key = 5678;

    int shmid;

    struct node *head;

    if ((shmid = shmget(key, sizeof(struct node), IPC_CREAT | 0666)) < 0) {
        perror("shmget");
        exit(1);
    };

    head = struct node*(shmat(shmid, (void *) 0, 0));

    head->val = 0;
    head->next= 0;

    append(head,2);
    append(head,5);
    append(head,6);

    exit(0);
}

void append(struct node *q,int val)

{
    struct node *temp1,*temp2;

    if (q->next == 0)

    {
        temp1=malloc(sizeof(struct node));
        temp1->val = val;
        temp1->next = 0;
        q->next = temp1;
    }

    else

    {
        temp2=malloc(sizeof(struct node));
        temp2->val = val;

        temp1 = q->next;
        while(1)
        {
            if (temp1 == 0)
            {
                temp1=temp2;
                break;
            }
            else
                temp1=temp1->next;
        }
    }

    return;

}

4 个答案:

答案 0 :(得分:2)

我不知道Beej是谁,但他写得很好guides,他为Shared memory segments撰写了一篇。

答案 1 :(得分:1)

你有很多选择:

  • 使用进程间通信(套接字,命名管道等)将重复列表发送到需要复制的每个进程。您将有重复的列表,这可能意味着您需要重复工作,并且您将遇到保持列表同步的问题 - 这可能与您的问题相关或不相关。
  • 使用列表服务器和进程间通信来请求或设置列表元素。您需要优雅地处理客户端永远不会返回列表项的情况(可能有心跳和/或预留时间)
  • 使用共享内存直接共享进程之间的列表。你需要非常小心锁定,它不能在不同的系统上工作。
  • 使用fork(),让子进程继承列表。与第一个解决方案一样,您最终将获得具有(可能)重复工作或重复元素的重复列表。与第三种解决方案一样,这不适用于各种系统。
  • 使用上述的一些组合。

答案 2 :(得分:0)

简单回答:不要。

多个进程的好处是您没有共享内存。这使您可以与其他进程隔离。在设计和稳健性方面,拥有“仅数据”障碍可以带来很大的好处。

相反,让生产过程将新数据(作为数据)发送到消费过程。这可以通过STDIN / STDOUT或套接字来完成,甚至可以像文件一样低技术。

答案 3 :(得分:0)

您不能将malloc用于单个节点的原因是因为malloc将指针返回到给定进程的堆中。指针对于具有自己的堆的另一个进程没有任何意义。该地址在两个进程中都可能有效,但它引用的“物理”内存将不同。

如果您正在使用shmget,则需要为每个节点使用它(或者创建一个更大的块,然后像已经建议的那样使用偏移量)。如果为每个节点使用了单独的shmget调用,则该键可以是列表中的next指针。这将是一种“简单”的实现方式,但它可能不是一个好主意。我相信共享内存对象存在系统范围的限制。我认为它是由SHMMNI定义的,在我刚检查的系统上是4096。

实现它的另一种方法是简单地使一个进程成为列表的所有者(创建和删除节点的进程)。然后使用单个共享内存对象在两个进程之间进行通信以分发各个节点。然后使用共享信号量(semget,semop等)进行同步。