使用 send 的時候要小心的事情是 send message 就真的是寄出去而已,對方有沒有收到,甚至是該 process 是不是還在都不會有任何回饋,雖然乍看之下有點不方便,但是盡可能的使用這種 non-blocking 的方式來傳遞訊息,是 Elixir concurrency 的核心理念,雖然有時候還是需要,但是要盡可能的消除送出訊息後就乾等的情況,後續在 OTP 章節介紹 cast 與 call 這些更方便的用法時就會比較清楚了。
那我現在假如就是需要等對方回覆要如何實現呢?有點像是寫信給別人要記得寫寄件地址對方才能回信
使用 self()
得到目前的 pid 再送過去,接著執行 receive 來等待對方使用 pid 回覆:
defmodule Server do
def start do
spawn(fn -> run() end)
end
def run do
receive do
pid ->
IO.puts("Server: 收到了! 停一秒假裝在處理")
Process.sleep(1000)
send(pid, "處理好了")
end
run()
end
end
defmodule Sender do
def ping(pid) do
send(pid, self())
IO.puts("Sender: 送出了等待回覆中")
receive do
message ->
IO.puts("Sender: 收到了回覆: #{message}")
end
end
end
server_pid = Server.start()
Sender.ping(server_pid)
執行結果:
iex(4)> server_pid = Server.start()
#PID<0.119.0>
iex(5)> Sender.ping(server_pid)
Sender: 送出了等待回覆中
Server: 收到了! 停一秒假裝在處理
Sender: 收到了回覆: 處理好了
:ok