चलें कोड के माध्यम से चलना:
-module(ring).
-export([start/2, node/2]).
नाम node
एक है मैं से बचने क्योंकि Erlang में एक नोड() कुछ मशीन पर चल रहा एक Erlang वी एम का अर्थ है - आम तौर पर कई नोड्स कई मशीनों पर चलने । मैं इसे ring_proc
या ऐसा कुछ कहूंगा।
node(NodeNumber, NumberOfNodes) ->
NextNodeNumber = (NodeNumber + 1) rem NumberOfNodes,
NextNodeName = node_name(NextNodeNumber),
इसी को हम अंडे देने के लिए कोशिश कर रहे हैं, और हम अगले नोड के लिए एक नंबर और अगले नोड का नाम मिलता है। चलो एक अन्तराल के रूप में node_name/1
को देखो:
node_name(NodeNumber) ->
list_to_atom(lists:flatten(io_lib:format("node~w", [NodeNumber]))).
यह समारोह एक बुरा विचार है। आपको एक स्थानीय नाम की आवश्यकता होगी जिसे परमाणु होना चाहिए, इसलिए आपने एक ऐसा फ़ंक्शन बनाया है जो मनमाने ढंग से ऐसे नाम बना सकता है। यहां चेतावनी यह है कि परमाणु तालिका कचरा और सीमित नहीं है, इसलिए यदि संभव हो तो हमें इससे बचना चाहिए। इस समस्या को हल करने की चाल इसके बजाय पिड्स को पास करना और रिवर्स में अंगूठी बनाना है। अंतिम प्रक्रिया तो अंगूठी की शादी होगी:
mk_ring(N) ->
Pid = spawn(fun() -> ring(none) end),
mk_ring(N, Pid, Pid).
mk_ring(0, NextPid, Initiator) ->
Initiator ! {set_next, NextPid},
Initiator;
mk_ring(N, NextPid, Initiator) ->
Pid = spawn(fun() -> ring(NextPid) end),
mk_ring(N-1, Pid, Initiator).
और फिर हम अपने प्रारंभ समारोह पुनर्लेखन कर सकते हैं:
start(NumberOfNodes, NumberOfCircuits) ->
RingStart = mk_ring(NumberOfNodes)
RingStart ! {operate, NumberOfCircuits, self()},
receive
done ->
RingStart ! stop
end,
ok.
अंगूठी कोड तो की तर्ज पर कुछ है:
ring(NextPid) ->
receive
{set_next, Pid} ->
ring(Pid);
{operate, N, Who} ->
ring_ping(N, NextPid),
Who ! done,
ring(NextPid);
ping ->
NextPid ! ping,
ring(NextPid);
stop ->
NextPid ! stop,
ok
end.
और अंगूठी के आसपास कुछ आग N बार:
ring_ping(0, _Next) -> ok;
ring_ping(N, Next) ->
Next ! ping
receive
ping ->
ring_ping(N-1, Next)
end.
(इस कोड में से कोई भी इस तरह से परीक्षण नहीं किया गया है, इसलिए यह बहुत गलत हो सकता है)।
अपने कोड से बाकी के लिए:
receive
CircuitNumber ->
io:format("Node ~p Circuit ~p~n", [NodeNumber, CircuitNumber]),
मैं कुछ परमाणु के साथ CircuitNumber
को टैग चाहते हैं: {run, CN}
।
NextCN = if NodeNumber =:= NumberOfNodes - 1 -> CN -1;
NodeNumber =/= NumberOfNodes - 1 -> CN
end,
अगले भाग यहाँ:
LastNode = NodeNumber =:= NumberOfNodes - 1,
NextCircuitNumber = case LastNode of
true ->
CircuitNumber - 1;
false ->
CircuitNumber
end,
यह एक करता है, तो साथ किया जा सकता
if
NextCircuitNumber > 0 ->
NextNodeName ! NextCircuitNumber;
true ->
ok
end,
if
CircuitNumber > 1 ->
node(NodeNumber, NumberOfNodes);
true ->
ok
end
, true
मामले की जरूरत है जब तक आप इसे कभी नहीं मारा। अगर if
में कुछ भी मेल नहीं खाता है तो प्रक्रिया क्रैश हो जाएगी। कोड को दोबारा संभव करना संभव है क्योंकि निर्माण संकेतों पर निर्भर न करें, जैसे कि मेरे संकेतों के उपरोक्त कोड।
इस समस्या से कई परेशानियों से बचा जा सकता है। वर्तमान कोड के साथ एक समस्या यह है कि अगर अंगूठी में कुछ दुर्घटनाग्रस्त हो जाता है, तो यह टूट जाता है। हम अंगूठी को एक साथ जोड़ने के लिए spawn
के बजाय spawn_link
का उपयोग कर सकते हैं, इसलिए ऐसी त्रुटियां पूरी अंगूठी को नष्ट कर देगी। इसके अलावा हमारे ring_ping
फ़ंक्शन क्रैश हो जाएगा जब यह रिंग चालू होने पर एक संदेश भेजा जाता है। यह कम किया जा सकता है, सबसे आसान तरीका शायद अंगूठी प्रक्रिया यह जानता है ऐसी है कि वह वर्तमान में काम कर रहा है की स्थिति में परिवर्तन और ring
में ring_ping
गुना है। आखिरकार, हमें शायद शुरुआती स्पॉन को भी लिंक करना चाहिए ताकि हम लाइव रिंग के साथ खत्म न हों, लेकिन किसी के पास इसका कोई संदर्भ नहीं है। शायद हम प्रारंभिक प्रक्रिया को पंजीकृत कर सकते हैं ताकि बाद में अंगूठी पकड़ना आसान हो।
start
समारोह दो तरीकों से भी बुरा है। सबसे पहले, हम make_ref()
का उपयोग करना चाहिए के साथ एक अद्वितीय संदेश को टैग और टैग प्राप्त करने के लिए है, तो किसी अन्य प्रक्रिया भयावह नहीं किया जा सकता और जब तक अंगूठी काम करता है बस शुरू करने के लिए प्रक्रिया done
भेजें। हमें यह काम करते समय, मॉनिटर पर भी रिंग पर जोड़ना चाहिए। अन्यथा हमें कभी सूचित नहीं किया जाएगा, जब हम done
संदेश (टैग के साथ) की प्रतीक्षा कर रहे हैं तो रिंग क्रैश होना चाहिए। ओटीपी दोनों तरह से इसके तुल्यकालिक कॉल में करता है।
अंत में, अंत में: नहीं, आपको पंजीकरण को साफ करने की आवश्यकता नहीं है।
अच्छी टिप्पणियां यहां! –