[elixir! #0072] 當在午夜寫入一個文件時,發生了什麼

夜深人靜,是寫代碼的好時間。git

上一篇文章中咱們經過 erlang 的 trace 功能瞭解到了打印字符串是經過消息傳遞來完成的。那麼,一樣是屬於 IO,寫入文件是否也是經過消息傳遞呢?github

爲此我特意寫了一個簡單的 trace 庫, 能夠把一個進程收到和發出的消息都打印出來。segmentfault

咱們的試驗代碼是這樣的:服務器

def test do
    spawn(fn ->
      BonyTrace.start(self())

      File.write!("lol.log", "hello")
    end)
  end

一運行,果真打印了很多消息:spa

#PID<0.389.0> SENT TO: #PID<0.58.0>                    +0.000000s
MESSAGE: {:"$gen_call", {#PID<0.389.0>, #Reference<0.2899216400.2129133569.149481>}, {:open, "lol.log", [:binary, :write]}}
#PID<0.389.0> RECEIVED                                 +0.000616s
MESSAGE: {#Reference<0.2899216400.2129133569.149481>, {:ok, #PID<0.391.0>}}
#PID<0.389.0> SENT TO: #PID<0.391.0>                   +0.000010s
MESSAGE: {:io_request, #PID<0.389.0>, #Reference<0.2899216400.2129133571.150072>, {:put_chars, :latin1, "hello"}}
#PID<0.389.0> RECEIVED                                 +0.000175s
MESSAGE: {:io_reply, #Reference<0.2899216400.2129133571.150072>, :ok}
#PID<0.389.0> SENT TO: #PID<0.391.0>                   +0.000006s
MESSAGE: {:file_request, #PID<0.389.0>, #Reference<0.2899216400.2129133571.150073>, :close}
#PID<0.389.0> RECEIVED                                 +0.000151s
MESSAGE: {:file_reply, #Reference<0.2899216400.2129133571.150073>, :ok}
#PID<0.389.0> RECEIVED                                 +0.000004s
MESSAGE: {:DOWN, #Reference<0.2899216400.2129133571.150073>, :process, #PID<0.391.0>, :normal}

咱們來解讀一下:code

  1. 首先發消息給 文件服務器, 要求 open 文件。
  2. 而後收到 :ok 回覆,以及文件的 owner 進程。
  3. 向 owner 進程發送 io 請求,寫入文件。
  4. 收到 io 回覆。
  5. 想 owner 進程發送 file 請求,關閉文件。
  6. 收到 file 回覆。
  7. 收到 owner 進程正常退出的消息。(由於 monitor 了)。
相關文章
相關標籤/搜索