如何使序列化并行运行

How to make serialization run in parallel

本文关键字:运行 并行 序列化 何使      更新时间:2023-10-16

伙计们,如果我有一个树结构,并且我想序列化树和子节点。如何并行地对每个节点进行序列化。如果我给每个节点分配一个独立的任务,那么输出数据就会混乱。是否存在一些并发序列化模式?

编辑:如果结构不是树,而是DAG?如何处理这种结构?如何序列化DAG并使序列化并发。

这是递归并行或Fork/Join并行的理想问题。

在树的每个级别,生成一个任务,将每个节点序列化到临时缓冲区,然后等待这些任务并加入缓冲区。例如(假设为二叉树(

std::string serialize_tree(tree t)
{
     std::future<std::string> left_rep=std::async(serialize_tree,tree.left_node);
     std::future<std::string> right_rep=std::async(serialize_tree,tree.right_node);
     return left_rep.get()+right_rep.get(); // plus any further formatting
}

显然,您需要检查空树或叶节点,或者其他什么,但这应该会给您一个想法。

EDIT:要处理DAG,可以将与依赖项相关联的future传递给异步调用,这样每个任务都会显式地等待完成所需的任务。

从您非常简短的描述中,还不清楚您有什么限制,所以我将大致回答。

如果你想并行处理树中的节点,同时又想保持处理结果的有序性,你可以这样做。

  1. 按照想要得到结果的顺序,给每个节点一个数字1-N
  2. 把节点和指定的编号一起交给一些可以并行处理事情的"机器"。这里有很多选择如何做事
  3. 等待所有操作完成,然后根据指定的编号对结果进行排序

在这里,通过在整个链中保持#1中给出的编号来保持排序。

步骤#2可以是一个线程池支持的类,您只需向其中添加项(数字节点对(。

在DAG上运行并行作业是大多数构建工具用来编译软件的功能。在单线程/进程环境中,经典的解决方案是使用拓扑排序对任务进行排序,然后按该顺序处理作业。

但是,在多线程/进程环境中,必须确保在完成节点的依赖关系之前,未处理节点的任务。这意味着您必须维护一个具有阻塞工作者的队列。您还必须保持不变,即队列中的节点已准备就绪(它们的依赖关系已完成处理(。

一种可能的实现是为每个节点维护一个依赖性计数器;当它的一个依赖项完成时,减少计数器。如果计数器达到0,请在队列中插入节点。