菌種你從上司的孩子「:
-module(ch_sup).
-behaviour(supervisor).
-export([start_link/0, init/1, start_child/1]).
start_link() -> supervisor:start_link({local, ?MODULE}, ?MODULE, []).
init([]) -> {ok, {{simple_one_for_one}, [{ch, {ch, start_link, []}, transient, 1000, worker, [ch]}]}}.
start_child(Data) -> supervisor:start_child(?MODULE, [Data]).
與ch_sup啓動:start_child/1(數據是什麼)。
實現你的孩子作爲gen_server:
-module(ch).
-behaviour(gen_server).
-record(?MODULE, {speed}).
...
get_speed(Pid, Timeout) ->
try
gen_server:call(Pid, get, Timeout)
catch
exit:{timeout, _} -> timeout;
exit:{noproc, _} -> died
end
.
...
handle_call(get, _From, St) -> {reply, {ok, St#?MODULE.speed}, St} end.
您現在可以使用超級獲得運行列表孩子和查詢他們,儘管你必須接受孩子在獲得兒童名單之間死亡的可能性並打電話給他們,顯然一個孩子可能因爲某種原因而活着,但沒有迴應,或者有錯誤迴應等。
上面的get_speed/2函數返回{ok,Speed}或死亡或超時。您仍然可以根據您的應用需求進行適當的過濾。列表理解容易,這裏有一些。
只是速度:
[Speed || {ok, Speed} <- [ch:get_speed(Pid, 1000) || Pid <-
[Pid || {undefined, Pid, worker, [ch]} <-
supervisor:which_children(ch_sup)
]
]].
PID和速度元組:
[{Pid, Speed} || {Pid, {ok, Speed}} <-
[{Pid, ch:get_speed(Pid, 1000)} || Pid <-
[Pid || {undefined, Pid, worker, [ch]} <-
supervisor:which_children(ch_sup)]
]
].
所有結果,包括超時和孩子,你有他們在這之前死 '死亡' 的結果:
[{Pid, Any} || {Pid, Any} <-
[{Pid, ch:get_speed(Pid, 1000)} || Pid <-
[Pid || {undefined, Pid, worker, [ch]} <-
supervisor:which_children(ch_sup)]
]
].
在大多數情況下,您幾乎可以肯定除了速度之外不需要其他任何東西,因爲wh你打算怎麼處理死亡和超時?你希望那些死去的人會被主管重新塑造,所以當你知道這個問題時,問題或多或少是固定的,超時和任何錯誤一樣,都是一個單獨的問題,要以你看到的任何方式來處理適合...雖然沒有必要將故障修復邏輯與數據檢索邏輯混合起來。
現在,所有這些,我認爲你在你的文章中得到的問題,但我不太清楚,1000的超時是爲每個電話,並且每個電話是另外,對於1000個1秒超時的孩子,可能需要1000秒才能產生結果。製作時間超時1ms的可能是答案,但做正確是一個比較複雜一點:
get_speeds() ->
ReceiverPid = self(),
Ref = make_ref(),
Pids = [Pid || {undefined, Pid, worker, [ch]} <-
supervisor:which_children(ch_sup)],
lists:foreach(
fun(Pid) -> spawn(
fun() -> ReceiverPid ! {Ref, ch:get_speed(Pid, 1000)} end
) end,
Pids),
receive_speeds(Ref, length(Pids), os_milliseconds(), 1000)
.
receive_speeds(_Ref, 0, _StartTime, _Timeout) ->
[];
receive_speeds(Ref, Remaining, StartTime, Timeout) ->
Time = os_milliseconds(),
TimeLeft = Timeout - Time + StartTime,
receive
{Ref, acc_timeout} ->
[];
{Ref, {ok, Speed}} ->
[Speed | receive_speeds(Ref, Remaining-1, StartTime, Timeout)];
{Ref, _} ->
receive_speeds(Ref, Remaining-1, StartTime, Timeout)
after TimeLeft ->
[]
end
.
os_milliseconds() ->
{OsMegSecs, OsSecs, OsMilSecs} = os:timestamp(),
round(OsMegSecs*1000000 + OsSecs + OsMilSecs/1000)
.
這裏每次打電話都催生了一個不同的過程和收集的答覆,直到「主超時」或者他們有全部收到。代碼已經基本上被剪切粘貼從各種作品,我已經躺在,並手動編輯和搜索替換,匿名它,並刪除多餘,所以它可能大多是compilable質量,但我不承諾我沒有破壞任何東西。
什麼是實際問題?你是否在實現任何選項時遇到困難,如果是的話,你應該問一些與之相關的東西。否則,這將主要取決於您的使用情況。 –
我同意亞當看到這更像一個設計問題,但沒有足夠的任何建議的信息。爲什麼有1000-2000個孩子包含國家。爲什麼有進程返回計數和發出調用而不是返回這些孩子,並讓調用者決定要做什麼?什麼是讀/寫比率?非功能性要求是什麼?低延遲或吞吐量更重要嗎?它是主要功能還是系統其餘部分有多大?等等。沒有額外的信息,對我來說沒有多大意義。 –
寫這個問題的原因很簡單:erlang給出了編寫基於actor的程序的簡單方法,OTP給予了標準化。首先,我寫的程序沒有OTP,理解程序邏輯很複雜。添加OTP後,它變得平坦和簡單。 在這裏,我得到了一個更復雜的行爲,同步/異步調用。我問道,如果其他erlang開發者會遇到類似問題,他們會選擇哪一種。 或者這個問題成爲不好的設計和答案是 - 做到這一點簡單,沒有1000(或更多)演員 – kolko