Elixir IEx shell,如何突破当前的“接收”块

Elixir IEx shell, how to break out of current `receive` block

我是 elixir 的新手,在 iex shell 中尝试学习,我是一个菜鸟问题。

为简单起见,我们将当前 shell 会话进程称为“主进程”。

我生成了一个子进程,在“主进程”中写了一个 receive 块来监听子进程。当按下回车键时,它会将“主进程”置于 waiting 状态。这基本上冻结了“主进程”,使其对进一步的输入没有反应。

很多次我都错误地卡在了这个状态。如果我搞砸了,我需要关闭 shell 并重新开始,丢失所有状态和设置。

我的问题:有没有办法withdraw/invalidate/break脱离工作receive块?

或者有什么方法可以启动另一个会话,而不会终止前一个会话,然后向它发送一些消息以将其解冻?

我认为您不能中断 receive,您可以使用另一个进程的 PID 终止该进程或为其设置一个 timeout,然后您可以取回会话的控制权如果在此超时之间未收到任何内容 window.

receive do
  a -> a
after
  1_000 -> "nothing after 1s"
end

看看https://elixir-lang.org/getting-started/processes.html#send-and-receive

采用第二种方法需要一些工作。每个 iex 实例都是一个单独的 OTP 节点,因此为了让这两个实例相互通信,您需要执行以下操作:

  1. 指定相同的 cookie 和不同的 名称:
iex --cookie foo --name "node1@127.0.0.1"
iex --cookie foo --name "node2@127.0.0.1"
  1. 将全局名称与接收方节点关联(运行 in node1):
:global.register_name(:node1, self())
  1. 将 node1 连接到 node2(运行 in node1):
Node.connect(:"node2@127.0.0.1")

现在,您可以使用 receive 开始收听 node1 中的消息。要从 node2 向 node1 发送消息,请找出其在集群中的 PID 并在那里分发消息:

:global.whereis_name(:node1) |> send "Hello!"