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

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


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

如果有人能告诉我实现它的方法,那么对我来说将是非常有帮助的。

我有一个想法,如下所述:我可以做这样的事情,我创build节点的大小的共享内存的一段。 然后,我只是处理malloc?我的意思是我将创buildshmget(键,SHMSZ,IPC_CREAT | 0666)的帮助下,SHMSZ将是结构节点的大小的共享内存。 所以我只在两个进程之间共享列表头。 列表中的第一个条目将具有除链接条目之外的所有值,这些链接条目将指向列表中的下一个条目,并且该条目是在malloc的帮助下创build的,因为在我的应用程序中,因为其他进程将只读,而一个进程将要添加/删除列表中的条目。

我收到了一个回复,告诉我我不能使用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; } 

我不知道Beej是谁,但是他写了很棒的指南 ,他写了一个共享内存段 。

你有一堆选择:

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

简单的回答:不要。

多个进程的好处是你没有共享内存。 这使您与其他进程隔离。 就设计和稳健性而言,拥有“仅数据”的屏障给了您极大的好处。

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

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

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

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