我尝试发送来自同一父级的subprocess之间的链接列表。 Child1需要find列表中的第一个素数,然后将其删除,然后将其倍数发送给Child2。 Child2做同样的事情,它发送到Child3和ChildN做同样的,并发送到Child1。 然而,我试图发送地址数据而不是所有的数字,但这是一种正确的方式,因为我可能会强制我的subprocess进入另一个地址空间。 那么你认为最好的方式是什么或者其他方式而不是发送地址?
您还可以使用System V共享内存(查看shmat
函数)或mmap
来在进程之间共享内存。 Boost.Interprocess有一个围绕这些调用的C ++包装,这样你就可以直接在共享内存中创建一个链表而不需要复制。
我假设你正在尝试使用多处理实现Eratothenes筛。 除非我误解你所描述的内容,否则你的算法可以改进。 你所描述的是一个系统,其中一个数字列表被传递给一个子进程,该进程在把列表的其余部分交给下一个子进程之前检查所有的值。
我将把这个算法作为一个进程的流水线来实现
Generator -> [Prime2] -> Prime3 -> Prime5 -> Prime7 -> ... PrimeP
下一个Prime进程是由链上最后一个进程创建的。 所以当生成8时,它被Prime2过滤掉并丢弃。 当发送9时,它被传递给Prime2,Prime2将其传递给Prime3,将其丢弃。 10则下降了2,而11则通过整个链条,而且由于Prime7之后在链条上没有链接,它以11为参数推出了一个新的过程。 Prime2应该像生成一样快地消费价值。 Prime 2正在计算20时,Prime3正在计算19,依此类推。 (优化:Prime2在实现视图中基本上是不必要的)。
当进程PrimeP创建新的进程PrimeN时,父进程创建2个管道,一个用于写入新进程,另一个用于从新进程读取。 然后,每个非终端进程节点将总共具有4个管道:两个正在到达/来自后继节点,并且两个正在到达/来自前任节点。 每个节点的未使用的末端可以关闭,但这不是严格必要的。
这个算法很好,因为管道在读取之前阻塞,直到读取一个值。 数字可以通过管道作为二进制数据发送:
read(parent, &value, sizeof(value))
从以前的过程中读取数据
write(stdout, &value, sizeof(value))
将数据写入下一个链接。
当生成最后一个数字时,链可以通过几种方式暂停:
如果发生器需要收集所有的值,那么当PoisonPill发送时,可以使用另一组管道将它们发送回链路; 第二个PoisonPill也可以用作某种控制。
这有一些问题:
要回答你的问题,发送一个链表没有任何意义,据我所知。 你要把它们一个接一个送到链条上,或者至少把它们当作一个数组。
将索引发送到列表而不是指针,或者将列表压缩到数组中,然后发送。
(听起来像是在实施Eratothenes的Sieve,无论如何它在数组上工作得更快。)
如果您正在使用管道,则通过不将该条目写入管道来“删除”条目。 所以,不要担心从列表中删除数据,只需考虑是否将从输入管道读取的条目写入输出管道。