IEX 在生成等待接收消息的进程后出现停顿。

huangapple go评论66阅读模式
英文:

IEX stalling after spawning process that waits to receive messages

问题

I'm completely new to Elixir but had to use Erlang for a piece of coursework and I am currently trying to line by line translate it to Elixir.

我完全不懂Elixir,但不得不在一项课程作业中使用Erlang,目前正在尝试逐行将其转换为Elixir。

I have it compiling successfully and everything seems good to go.

我已成功编译它,一切看起来都没问题。

I want to start a server process using the start_server() function, which spawns a server on a new process and then send it a message from iex:

我想使用start_server()函数启动一个服务器进程,它会在一个新进程上生成一个服务器,然后从iex发送一条消息:

  def server(s, us, sums, n) do
    IO.puts("服务器在线")
    receive do
      :finished ->
        :ok
        ...更多消息模式
        end
    end
  end

  def start_server() do
    server_pid = spawn(server(0, 0, [], 0))
    Process.register(server_pid, :server)
    IO.puts("服务器已启动并注册。应该正在等待消息")
  end

However, when running start_server in iex, it seems to be stuck waiting for a message, not allowing me to send any more commmands, unlike what I'm used to in Eshell.

但是,在iex中运行start_server时,它似乎被卡住等待消息,不允许我发送更多命令,与我在Eshell中的经验不同。

I looked online for simple examples of this same scenario (spawning a process that is waiting for messages) and found this "Salutator" example, but following its instructions lead to the same issue. Is there something simple that I am missing?

我在网上查找了相同情况的简单示例(生成一个等待消息的进程),找到了这个"Salutator"示例,但按照其说明仍然出现了相同的问题。我是否漏掉了什么简单的东西?

英文:

I'm completely new to Elixir but had to use Erlang for a piece of coursework and I am currently trying to line by line translate it to Elixir.

I have it compiling successfully and everything seems good to go. I want to start a server process using the start_server() function, which spawns a server on a new process and then send it a message from iex:

  def server(s, us, sums, n) do
    IO.puts("Server online")
    receive do
      :finished ->
        :ok
        %... More message patterns 
        end
    end
  end

  def start_server() do
    server_pid = spawn(server(0, 0, [], 0))
    Process.register(server_pid,:server)
    IO.puts("server started and registered. Should be waiting for message")
  end

However, when running start_server in iex, it seems to be stuck waiting for a message, not allowing me to send any more commmands, unlike what I'm used to in Eshell. I looked online for simple examples of this same scenario (spawning a process that is waiting for messages) and found this "Salutator" example, but following it's instructions lead to the same issue. Is there something simple that I am missing?

答案1

得分: 1

当使用 spawn 时,你需要传递一个要运行的函数,就像这两个中的一个:

spawn(fn -> IO.puts("来自进程 #{inspect(self())} 的问候") end)
spawn(&MyModule.print_my_pid/0)

你所做的相当于这样:

IO.inspect(self())
spawn(IO.inspect(self()))
# 这段代码会输出:
#PID<0.108.0>
#PID<0.108.0>
** (ArgumentError) 在给定的参数中发现了错误:

  * 第一个参数:不是一个函数

    :erlang.spawn(#PID<0.108.0>)
    iex:6: (file)

如你所见,两次 self() 调用返回的都是相同的 PID - 它们都在父进程上运行。然后,spawn 被调用,其输出不是一个函数,因此是无效的。

你可能想要的是在匿名函数中包装 server 调用:

server_pid = spawn(fn -> server(0, 0, [], 0) end)
英文:

When using spawn, you need to pass it a function to run, like one of these two:

spawn(fn -&gt; IO.puts(&quot;hi from pid #{inspect(self())}&quot;)
spawn(&amp;MyModule.print_my_pid/0)

What you're doing is the equivalent of this:

IO.inspect(self())
spawn(IO.inspect(self()))
# This code prints:
#PID&lt;0.108.0&gt;
#PID&lt;0.108.0&gt;
** (ArgumentError) errors were found at the given arguments:

  * 1st argument: not a fun

    :erlang.spawn(#PID&lt;0.108.0&gt;)
    iex:6: (file)

As you can see, both the self() calls had the same PID - they both ran on the parent process. Then, spawn was called with the output of that, which is not a function and thus invalid.

What you want here is probably to wrap the server call in an anonymous function:

server_pid = spawn(fn -&gt; server(0, 0, [], 0) end)

huangapple
  • 本文由 发表于 2023年6月12日 02:50:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/76452025.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定