英文:
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 -> IO.puts("hi from pid #{inspect(self())}")
spawn(&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<0.108.0>
#PID<0.108.0>
** (ArgumentError) errors were found at the given arguments:
* 1st argument: not a fun
:erlang.spawn(#PID<0.108.0>)
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 -> server(0, 0, [], 0) end)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论