【问题标题】:Elixir IEx shell, how to break out of current `receive` blockElixir IEx shell,如何突破当前的“接收”块
【发布时间】:2021-07-05 05:44:18
【问题描述】:

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

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

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

很多时候我不小心陷入了这种状态。如果我搞砸了,我需要关闭 shell 并重新开始,丢失所有的状态和设置。

我的问题:有没有办法撤销/无效/突破工作中的receive 块?

或者也许有一种方法可以让我开始另一个会话,而不杀死前一个会话,然后向它发送一些消息以解冻它?

【问题讨论】:

    标签: elixir elixir-iex


    【解决方案1】:

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

    1. 为每个cookie指定相同的不同的名称:
    iex --cookie foo --name "node1@127.0.0.1"
    iex --cookie foo --name "node2@127.0.0.1"
    
    1. 将全局名称与接收节点关联(在node1 中运行):
    :global.register_name(:node1, self())
    
    1. 将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 可以解决我的问题,好主意。只需要记住每次都这样做。仍然希望看到其他答案,如果没有,我会接受这个。
    猜你喜欢
    • 2021-06-27
    • 2015-06-14
    • 1970-01-01
    • 2016-10-21
    • 2020-02-16
    • 2023-03-26
    • 2017-08-10
    • 2014-01-08
    相关资源
    最近更新 更多