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 应用程序

为输入 iex shell 着色

Elixir shell 中的 Application.stop(...)

Elixir - 从命令行运行时记录器输出是彩色的,从 iex 运行时不是这样

使 elixir 应用程序在源代码更改时重新编译和重新加载