測試一下spawn一個process需要的時間
先來看以下這段code:-module(processes).-export([max/1]). max(N) -> Max = erlang:system_info(process_limit), io:format("Maximum allowed processes:~p~n",[Max]), statistics(runtime), statistics(wall_clock), L = for(1, N, fun() -> spawn(fun() -> wait() end) end), {_, Time1} = statistics(runtime), {_, Time2} = statistics(wall_clock), lists:foreach(fun(Pid) -> Pid ! die end, L), U1 = Time1 * 1000 / N, U2 = Time2 * 1000 / N, io:format("Process spawn time=~p (~p) microseconds~n", [U1, U2]).wait() -> receive die -> void end. for(N, N, F) -> [F()]; for(I, N, F) -> [F()|for(I+1, N, F)].
黃色部分是一個for function的定義,這個把N個F()的結果給放到一個 list中。
所以可以看到L是一個N個 spawned processes PIDs的list,每一個process只是單純的執行wait()。
wait to die!!!!!
然後在綠色部分做一個map的動作,這個mapping其實就是把process kill掉而已。再來就是把這N個process spawn用system time來算出執行時間。
在我的電腦上,結果如下:
Maximum allowed processes:262144
spawnedProcess spawn time=3.1 (1.55) microseconds
增加max allowed processes
262144 = 2^18我們試試看加大erlang emulator能乘載的processes數目:
其實就看你的電腦記憶體有多大,我開500萬個processes,因為記憶體只有16g,所以需要至少 > 10g,所以還沒開到500萬個就爆掉了。
timeout
這可以拿來寫成process waiting timeout:或是timer:
(沒有receive 會compile不過! 所以是為什麼?)
或是做buffer flushing:
這段code的意義是 由於after 0,所以馬上就timeout return true,但是在 return 之前,會先執行一次receive clause,所以match anything之後又recursively call itself,這樣就會一直把received到的東西給讀取(但是沒做任何事),直到再也沒有_Any可以match就結束了這個process。
如果拿掉after 0 clause的話,這個process要是沒有收到東西也不會結束自己。
利用timeout時候 (i.e. after 0)會先檢查receive clause的語言特性,可以做出很多變化,非常好用!
在語言層級支援這個還蠻神奇的。
一個可以 cancel的timer
-module(mtimer).-export([timer/2, start/2, cancel/1]). timer(Microsecs, Func) -> receive cancel -> void after Microsecs -> Func() end. start(Microsecs, Func) -> spawn(fun() -> timer(Microsecs, Func) end). cancel(Pid) -> Pid ! cancel.
這樣的架構就用到了after 的好處。使用如下:
沒有留言:
張貼留言