iT邦幫忙

2024 iThome 鐵人賽

DAY 30
0
Software Development

Elixir 多工 : Processes 與 OTP系列 第 30

30 使用遞迴數除錯

  • 分享至 

  • xImage
  •  

由於 BEAM VM 的特性,debug 時我們可以選擇關閉指定正在執行的 process 或是特定的指揮串,而不是只有直接關掉整個 instance 這個選擇。

這邊示範一下其中一種在 BEAM 內除錯的方式

使用 Process.infoProcess.list 這個組合就可以讓我們抓取最耗資源的 process

假如現在系統有一個沒效率的函式來加 1 到指定數字的加總

defmodule Calc do
  def sum(n), do: sum(n, 1)
  defp sum(0, acc), do: acc
  defp sum(n, acc), do: sum(n - 1, n + acc)
end

在 iex 裡我們使用 spawn 來模擬他在別的 process 執行,並給他一個很大的數字,讓他跑不完

# iex
spawn fn -> Calc.sum(10000000000) end

可以發現 就算有一個需要執行非常久的 process ,iex 本身還是可以正常執行,因為 scadular 在輪流執行 process 時,會有一定的 reduction 限制,不會永遠卡在一個 process 上。這個特點讓 BEAM 系統可以比較溫和的處理這方面的問題。

當然雖然衝擊不明顯但有問題還是要解決,除了我們可以在 observer 裡面看到這個特別耗資源的 process 之外

我們也可在 iex 裡,用 Process.list 與 Process.info 的組合來撈出最多 reductions 數的 process

list = Process.list() \
|> Enum.map(fn pid -> {Process.info(pid, :reductions) |> elem(1), pid} end) \
|> Enum.sort_by(fn {reductions, _} -> reductions end, :desc)
[
  {6468120000, #PID<0.114.0>},
  {360699, #PID<0.116.0>},
  {226790, #PID<0.50.0>},
  {127569, #PID<0.108.0>},
  {125492, #PID<0.130.0>},
  {83841, #PID<0.117.0>},
  {72692, #PID<0.45.0>},
  {34977, #PID<0.66.0>},
  {32731, #PID<0.70.0>},
  {27719, #PID<0.120.0>},
  {18495, #PID<0.115.0>},
  {11182, #PID<0.11.0>},
  ...

接著用 Process.exit 將它關閉就可以了

iex(7)> {_, pid} = hd(list)
{8039888000, #PID<0.114.0>}
iex(8)> Process.exit(pid, :kill)
true

上一篇
29 Process.info
系列文
Elixir 多工 : Processes 與 OTP30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言