有人可以告诉我 mi Task.await 有什么问题吗?

问题描述 投票:0回答:1

有了这段代码,我希望让孩子对给定的 number_list 执行 is_prime 函数并返回结果,但我在从 Task.await 方法检索结果时遇到问题。

defmodule LeaderWorker do
  def start() do
    children = [{Task.Supervisor,
      name: Task.SomeThingSupervisor,
    }]

    Supervisor.start_link(children, strategy: :one_for_one)
  end

  def run(number_list, num_workers) do
    results =
      number_list
      |> Task.async_stream(&check_prime/1, max_concurrency: num_workers)
      |> Enum.map(&Task.await/1)

    IO.inspect(results)
  end

  def check_prime(number) do
    prime = is_prime(number)
    IO.inspect({number, prime})
    {number, prime}
  end

  def is_prime(number) when number <= 1 do
    false
  end

  def is_prime(number) do
    not Enum.any?(2..(div(number, 2)), &(&1 != 1 and rem(number, &1) == 0))
  end
end

LeaderWorker.start()
number_list = [2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
LeaderWorker.run(number_list, 4)

这是我遇到的错误:

 elixir .\clean.ex
{2, false}
{3, true}
{4, false}
{5, true}
** (FunctionClauseError) no function clause matching in Task.await/2    

    The following arguments were given to Task.await/2:

        # 1
        {:ok, {2, false}}

        # 2
        5000

    Attempted function clauses (showing 1 out of 1):

        def await(%Task{ref: ref, owner: owner} = task, timeout) when timeout == :infinity or is_integer(timeout) and timeout >= 0

    (elixir 1.16.2) Task.await/2
    (elixir 1.16.2) lib/enum.ex:1708: anonymous fn/3 in Enum.map/2
    (elixir 1.16.2) lib/enum.ex:4396: anonymous fn/3 in Enum.map/2
    (elixir 1.16.2) lib/task/supervised.ex:386: Task.Supervised.stream_deliver/7
    (elixir 1.16.2) lib/enum.ex:4396: Enum.map/2
    clean.ex:14: LeaderWorker.run/2
    clean.ex:36: (file)

我正在尝试找到该问题的解决方案,以获得我应该拥有的 {number, boolean} 列表

multithreading concurrency process elixir
1个回答
0
投票

您可以像这样重写您的

run
函数:

  def run(number_list, num_workers) do
    stream =
      number_list
      |> Task.async_stream(&check_prime/1, max_concurrency: num_workers)

    Enum.reduce(stream, %{}, fn {number, prime}, acc -> Map.put(acc, number, prime) end)
  end

由于您使用的是流,因此您需要以某种方式收集项目,而不是简单地等待结果,

reduce
这里可以解决问题,但如果我错了,请有人纠正我:)

进行此更改后,您将得到以下结果作为输出:

{2, false}
{3, true}
{5, true}
{4, false}
{6, false}
{7, true}
{8, false}
{9, false}
{10, false}
{11, true}
© www.soinside.com 2019 - 2024. All rights reserved.