Elixir进程receive机制疑问:为何无法返回修改后的值?
Elixir进程receive机制及问题解决
为什么你看到的是发送的参数
send(pid, 1)这个函数本身的返回值就是你传入的第二个参数1,和目标进程里的receive处理逻辑无关——Elixir设计里send是异步操作,它只会把消息投递到目标进程的邮箱,然后立刻返回发送的内容,所以你执行完send后拿到的是1,不是处理后的结果。
receive的工作逻辑
receive的作用是从当前进程的邮箱中取出匹配的消息,执行对应的代码,但这段代码的返回值不会自动传递给发送消息的进程。因为Elixir的进程是完全隔离的,进程之间只能通过显式的消息传递来交换数据,没有函数调用那种直接返回值的机制。
实现预期效果的代码
要拿到处理后的2,需要让子进程把处理结果发回给父进程,修改代码如下:
defmodule Modifier do def loop do receive do # 接收包含发送者pid和消息的元组 {sender_pid, message} when is_integer(message) -> result = message + 1 # 把处理结果发回给父进程 send(sender_pid, result) end # 循环让进程持续处理后续消息 loop() end end
然后按以下方式调用,父进程主动接收子进程返回的结果:
# 启动子进程 pid = spawn(&Modifier.loop/0) # 发送消息时带上父进程的pid(self()获取当前进程pid) send(pid, {self(), 1}) # 父进程接收子进程返回的结果并输出 receive do result -> IO.puts(result) # 控制台会输出2 end
额外说明
- 如果父进程不调用
receive,子进程发回的结果会留在父进程的邮箱中,不会自动输出。 - 代码里的
loop()是让子进程保持运行状态,能持续处理多个消息;如果去掉loop(),子进程处理完第一个消息后就会退出。
内容的提问来源于stack exchange,提问作者IOEnthusiast
相关产品推荐
相关产品推荐

