Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在超时后终止Elixir进程_Elixir - Fatal编程技术网

如何在超时后终止Elixir进程

如何在超时后终止Elixir进程,elixir,Elixir,我如何启动长生不老药进程,然后在超时后将其杀死?我有这样的代码: defmodule OperationsManager do def run_operation do spawn fn -> # long operation end end end 内部操作可能持续太长时间,无法等待其结束,因此我需要从manager中终止该进程。我怎么做 编辑: 重要细节:我需要生成几个操作,所有操作都应该有单独的超时。您可以使用在进程之间发送消息来管理各种情况

我如何启动长生不老药进程,然后在超时后将其杀死?我有这样的代码:

defmodule OperationsManager do
  def run_operation do
    spawn fn -> 
      # long operation 
    end
  end
end
内部操作可能持续太长时间,无法等待其结束,因此我需要从manager中终止该进程。我怎么做

编辑:


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

您可以使用在进程之间发送消息来管理各种情况,例如:

parent_pid = self()
spawn_pid = spawn fn -> 
  # some code...
  # :timer.sleep(1_500)
  send(parent_pid, {:done, self()})
end
# wait a result from spawned proccess
receive do
  {:done, pid} -> "Got :done from #{inspect pid}"
after # 1s timeout
  1_000 -> Process.exit(spawn_pid, :kill)
end
# ensure that spawned process is finished or killed
Process.alive?(spawn_pid) # => false

我想看看长生不老药

您可以使用
task.yield
或多个任务
task.yield\u many
在给定的时间间隔内处理单个任务,尽管
task.yield
似乎更接近您可能需要的。 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()
def模块操作管理器do
def run_操作()do
task1=Task.async(fn()->操作(“任务1”,1)结束)
结果=任务产量(任务15000)
处理任务(任务1,结果)
task2=Task.async(fn()->操作(“任务2”,2)结束)
task4=Task.async(fn()->操作(“任务4”,4)结束)
task6=Task.async(fn()->操作(“任务6”,6)结束)
task8=Task.async(fn()->操作(“任务8”,8)结束)
结果=任务。产量(任务2,任务4,任务6,任务8],7000)
对于{task,res}
IO.write(“关闭超时任务:”)
IO.检查(任务)
任务。关机(任务:杀死)
{:好的,任务号}->
IO.puts(“{task_number}已完成”)
{:退出,_原因}->
#任务终止时的一些逻辑
结束
结束
def操作(任务编号、超时)do
:timer.sleep(超时*1000)
任务编号
结束
结束
OperationsManager.run_操作()

为了完整起见:erlang
:timer
模块有一个函数,该函数将在经过一段时间后强制终止进程

# 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)

但是只有在只有一次手术时才合适,不是吗?你是什么意思?每个派生的操作将返回一个PID。所以你可以用它们做任何你想做的事情。我的意思是,如果我在不同的时间生成两个操作,
receive
construction如何区分一个操作的超时和另一个操作的超时?但也许我遗漏了一些要点。这是一个太大的话题,不能发表评论。所以我建议读这篇文章:我刚刚开始学习长生不老药,所以也许我会有足够的问题来提高你的声誉,甚至更高:)这应该是答案!