gpt4 book ai didi

elixir - 从内部杀死 GenServer

转载 作者:行者123 更新时间:2023-12-04 22:57:25 25 4
gpt4 key购买 nike

考虑这样简单的 GenServer 模块:

defmodule Crap do
use GenServer

... #All the needed crap

def handle_info(:kill_me_pls, state) do
GenServer.stop(self)
{:noreply, state}
end

def terminate(_, state) do
IO.inspect "Look! I'm dead."
end

end

并考虑将这些表达式放入 repl:
{:ok, pid} = Crap.start_link

send_message_to_that_pid

这就是我开始思考的地方,因为 Process.alive? pid返回 true,但进程没有响应并且 terminate没有被调用,虽然如果我调用 GenServer.stop(pid)在“干净”进程(没有收到终止消息)上调用 repl 会正确终止它。如果停止调用接收到 :kill_me_pls 消息的进程会挂起 repl。

最佳答案

“从内部”停止 GenServer 的正确方法是返回 {:stop, reason, new_state}来自 handle_* 的值或 {:stop, reason, reply, new_state}来自 handle_call .您的代码失败的原因是调用 GenServer.stop向 GenServer 发送一个特殊的消息,因为 GenServer 是一个单独的进程并且当前在 handle_info ,它无法响应 stop调用,因此您的进程挂起/创建死锁。

这是正确的方法:

def handle_info(:kill_me_pls, state) do
{:stop, :normal, state}
end

你可以阅读更多关于可能的返回值,查看标题下的文本 Return valuesdocumentation of GenServer .

演示:
iex(1)> defmodule Crap do
...(1)> use GenServer
...(1)>
...(1)> def handle_info(:kill_me_pls, state) do
...(1)> {:stop, :normal, state}
...(1)> end
...(1)>
...(1)> def terminate(_, state) do
...(1)> IO.inspect "Look! I'm dead."
...(1)> end
...(1)> end
iex(2)> {:ok, pid} = GenServer.start Crap, []
{:ok, #PID<0.98.0>}
iex(3)> send(pid, :kill_me_pls)
"Look! I'm dead."
:kill_me_pls
iex(4)> Process.alive?(pid)
false

关于elixir - 从内部杀死 GenServer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39754803/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com