【问题标题】:How can I have a Map that all processes can access?我怎样才能拥有所有进程都可以访问的地图?
【发布时间】:2016-04-02 11:14:21
【问题描述】:

我正在构建一个多线程网络爬虫。

我启动了一个线程,它首先获取n href 链接并解析一些数据。然后它应该将这些链接添加到其他线程可以访问的已访问列表,并将数据添加到将在程序完成时打印的全局地图。然后线程启动新的n 新线程,它们都在做同样的事情。

如何设置所有线程都可以访问的已访问站点的全局列表以及所有线程也可以写入的全局地图。

【问题讨论】:

    标签: multithreading erlang elixir


    【解决方案1】:

    您不能在进程之间共享数据。这并不意味着您不能共享信息。

    通常的方法是要么使用一个特殊的进程(服务器)来负责这项工作:维护一个状态;要么在您的情况下,访问链接列表。

    另一种方法是使用ETS(或基于 ETS 构建的数据库 Mnesia),它旨在在进程之间共享信息。

    【讨论】:

    • 通常情况下,简单包装一些状态的进程是基于代理的。您可以向它发送消息以查询或获取状态。有关文档,请参阅elixir-lang.org/getting-started/mix-otp/agent.html(是的,我知道在 SO 上不赞成链接粘贴,因此只是评论:-))
    【解决方案2】:

    澄清一下,erlang/elixir 使用进程而不是线程。

    给定一个元素列表,一个通用的方法:

    • 一个名为 processed 的空列表保存到 ets、dets、mnesia 或某些 DB。
    • 新的元素列表根据processed 列表进行过滤,因此不会不必要地重复任务。
    • 对于过滤列表中的每个元素,都会运行一个任务(这反过来会产生一个进程),并对每个返回所需数据映射的元素执行一些工作。请参阅 Task module Task.async/1Task.yield_many/2 可能会有用。
    • 一旦所有任务都返回或产生,

      1. 所有地图或地图中的部分数据都已合并,并且可以在/根据需要/适当的情况下进行持久化。
      2. 任务未崩溃或超时的元素被添加到数据库中的processed 列表中。
    • 可以以不同方式处理崩溃或超时的任务。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-01-22
      • 1970-01-01
      • 2010-09-25
      • 1970-01-01
      • 2017-01-15
      • 2021-10-24
      • 1970-01-01
      相关资源
      最近更新 更多