如何在超时后杀死Elixir进程

hed*_*sky 3 elixir

如何启动Elixir进程,然后在超时后终止它?我有这样的代码:

defmodule OperationsManager do
  def run_operation do
    spawn fn -> 
      # long operation 
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

内部操作可能持续太长时间等待它的结束,所以我需要从管理器中删除该进程.我该怎么做?

编辑:

重要细节:我需要生成几个操作,并且所有操作都应该具有单独的超时.

Paw*_*rok 9

只是为了完整性:erlang :timer模块有一个功能kill_after,在经过一段时间后会强制终止进程.

# Kill the current process after 2 seconds 
:timer.kill_after(:timer.seconds(2))

# Kill pid after 2 minutes
:timer.kill_after(:timer.minutes(2), pid)
Run Code Online (Sandbox Code Playgroud)

  • 这应该就是答案! (2认同)

ste*_*n_m 7

我会看一下Elixir Task模块.

您可以使用Task.yieldTask.yield_many在给定时间间隔内执行多个任务来处理单个任务,尽管Task.yield看起来更接近您可能需要的任务.收益率返回{:ok, result}(成功返回),{:exit, reason}(任务崩溃)或:nil(超时间隔超过).您还可以考虑将任务放在监督树中.

以下代码基于elixir 1.2.1.

defmodule OperationsManager do
  def run_operation() do

    task1 = Task.async(fn() -> operation("task 1", 1) end)
    result = Task.yield(task1, 5000)
    process_task(task1, result)

    task2 = Task.async(fn() -> operation("task 2", 2) end)
    task4 = Task.async(fn() -> operation("task 4", 4) end)
    task6 = Task.async(fn() -> operation("task 6", 6) end)
    task8 = Task.async(fn() -> operation("task 8", 8) end)

    results = Task.yield_many([task2, task4, task6, task8], 7000)
    for {task, res} <- results do
      process_task(task, res)
    end

  end

  def process_task(task, res) do
    case res do
      :nil ->
        IO.write("shutting down timed out task: ")
        IO.inspect(task)
        Task.shutdown(task, :brutal_kill)
      {:ok, task_number} ->
        IO.puts("#{task_number} is complete")
      {:exit, _reason} ->
        # some logic when the task terminates
    end
  end

  def operation(task_number, timeout) do
    :timer.sleep(timeout * 1000)
    task_number
  end

end


OperationsManager.run_operation()
Run Code Online (Sandbox Code Playgroud)