Elixir IEx shell,如何突破当前的“接收”块
Posted
技术标签:
【中文标题】Elixir IEx shell,如何突破当前的“接收”块【英文标题】:Elixir IEx shell, how to break out of current `receive` block 【发布时间】:2021-07-05 05:44:18 【问题描述】:我是 elixir 的新手,在 iex
shell 中试验以学习,我是一个菜鸟问题。
为简单起见,我们将当前的 shell 会话进程称为“主进程”。
我生成一个子进程,在“主进程”中写一个receive
块来监听子消息。当按下回车键时,它会将“主进程”置于waiting
状态。这基本上冻结了“主进程”,使其对进一步的输入没有反应。
很多时候我不小心陷入了这种状态。如果我搞砸了,我需要关闭 shell 并重新开始,丢失所有的状态和设置。
我的问题:有没有办法撤销/无效/突破工作中的receive
块?
或者也许有一种方法可以让我开始另一个会话,而不杀死前一个会话,然后向它发送一些消息以解冻它?
【问题讨论】:
【参考方案1】:采用第二种方法需要一些工作。每个iex
实例都是一个单独的 OTP 节点,因此为了使这两个实例能够相互通信,您需要执行以下操作:
-
为每个cookie指定相同的和不同的名称:
iex --cookie foo --name "node1@127.0.0.1"
iex --cookie foo --name "node2@127.0.0.1"
-
将全局名称与接收节点关联(在
node1
中运行):
:global.register_name(:node1, self())
-
将node1连接到node2(在
node1
运行):
Node.connect(:"node2@127.0.0.1")
现在,您可以使用receive
开始收听node1
中的消息。要将消息从节点 2 发送到节点 1,请在集群中找出其 PID 并将消息发送到那里:
:global.whereis_name(:node1) |> send "Hello!"
【讨论】:
我喜欢这种方法!我知道我可以在 cwd 中放置一个.iex.exs
文件,但它无法处理 CLI 选项。有没有办法将选项保存在配置文件中?【参考方案2】:
我认为你不能中断 receive
,你可以使用另一个进程的 PID 杀死该进程或为其设置一个 timeout
,然后如果在这之间没有收到任何内容,你就可以重新控制会话超时窗口。
receive do
a -> a
after
1_000 -> "nothing after 1s"
end
看看https://elixir-lang.org/getting-started/processes.html#send-and-receive
【讨论】:
“使用它的PID杀死进程”你的意思是杀死“主进程”?这正是我想要避免的。 但是,输入after
可以解决我的问题,好主意。只需要记住每次都这样做。仍然希望看到其他答案,如果没有,我会接受这个。以上是关于Elixir IEx shell,如何突破当前的“接收”块的主要内容,如果未能解决你的问题,请参考以下文章
如何重新编译 Elixir 项目并从 iex 中重新加载它?
将 iex shell 附加到正在运行的 elixir 应用程序
Elixir shell 中的 Application.stop(...)