关于后端:elixir-0072-当在午夜写入一个文件时发生了什么

35次阅读

共计 1229 个字符,预计需要花费 4 分钟才能阅读完成。

夜深人静,是写代码的好工夫。

在上一篇文章中咱们通过 erlang 的 trace 性能理解到了打印字符串是通过消息传递来实现的。那么,同样是属于 IO,写入文件是否也是通过消息传递呢?

为此我顺便写了一个简略的 trace 库, 能够把一个过程收到和收回的音讯都打印进去。

咱们的试验代码是这样的:

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

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

一运行,果然打印了不少音讯:

#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}

咱们来解读一下:

  1. 首先发消息给 文件服务器,要求 open 文件。
  2. 而后收到 :ok 回复,以及文件的 owner 过程。
  3. 向 owner 过程发送 io 申请,写入文件。
  4. 收到 io 回复。
  5. 想 owner 过程发送 file 申请,敞开文件。
  6. 收到 file 回复。
  7. 收到 owner 过程失常退出的音讯。(因为 monitor 了)。

正文完
 0