एर्लैंग - कंसीडर

Erlang में समवर्ती प्रोग्रामिंग के लिए निम्नलिखित बुनियादी सिद्धांतों या प्रक्रियाओं की आवश्यकता होती है।

सूची में निम्नलिखित सिद्धांत शामिल हैं -

piD = स्पॉन (मज़ा)

एक नई समवर्ती प्रक्रिया बनाता है जो फन का मूल्यांकन करता है। नई प्रक्रिया कॉलर के समानांतर चलती है। एक उदाहरण इस प्रकार है -

उदाहरण

-module(helloworld). 
-export([start/0]). 

start() ->
   spawn(fun() -> server("Hello") end). 

server(Message) ->
   io:fwrite("~p",[Message]).

उपरोक्त कार्यक्रम का आउटपुट है -

उत्पादन

“Hello”

पिद! संदेश

पहचानकर्ता Pid के साथ प्रक्रिया के लिए एक संदेश भेजता है। संदेश भेजना अतुल्यकालिक है। प्रेषक प्रतीक्षा नहीं करता है लेकिन यह जारी रखता है कि यह क्या कर रहा था।‘!’ भेजने वाला कहा जाता है।

एक उदाहरण इस प्रकार है -

उदाहरण

-module(helloworld). 
-export([start/0]). 
start() -> 
   Pid = spawn(fun() -> server("Hello") end), 
   Pid ! {hello}. 

server(Message) ->
   io:fwrite("~p",[Message]).

प्राप्त ... अंत

एक संदेश प्राप्त करता है जिसे एक प्रक्रिया में भेजा गया है। इसके निम्नलिखित सिंटैक्स हैं -

वाक्य - विन्यास

receive
Pattern1 [when Guard1] ->
Expressions1;
Pattern2 [when Guard2] ->
Expressions2;
...
End

जब कोई संदेश प्रक्रिया में आता है, तो सिस्टम इसे पैटर्न 1 के खिलाफ (संभावित गार्ड गार्ड 1 के साथ) मेल करने की कोशिश करता है; यदि यह सफल होता है, तो यह एक्सप्रेशन 1 का मूल्यांकन करता है। यदि पहला पैटर्न मेल नहीं खाता है, तो यह पैटर्न 2 की कोशिश करता है, और इसी तरह। यदि कोई भी पैटर्न मेल नहीं खाता है, तो संदेश बाद की प्रक्रिया के लिए सहेजा जाता है, और प्रक्रिया अगले संदेश की प्रतीक्षा करती है।

सभी 3 आदेशों के साथ पूरी प्रक्रिया का एक उदाहरण निम्नलिखित कार्यक्रम में दिखाया गया है।

उदाहरण

-module(helloworld). 
-export([loop/0,start/0]). 

loop() ->
   receive 
      {rectangle, Width, Ht} -> 
         io:fwrite("Area of rectangle is ~p~n" ,[Width * Ht]), 
         loop(); 
      {circle, R} ->
      io:fwrite("Area of circle is ~p~n" , [3.14159 * R * R]), 
      loop(); 
   Other ->
      io:fwrite("Unknown"), 
      loop() 
   end. 

start() ->
   Pid = spawn(fun() -> loop() end), 
   Pid ! {rectangle, 6, 10}.

उपरोक्त कार्यक्रम के बारे में निम्नलिखित बातों पर ध्यान देने की आवश्यकता है -

  • लूप फ़ंक्शन को प्राप्त अंत लूप है। इसलिए जब कोई संदेश भेजा जाता है, तो उसे प्राप्त अंत लूप द्वारा संसाधित किया जाएगा।

  • एक नई प्रक्रिया शुरू की गई है जो लूप फ़ंक्शन पर जाती है।

  • संदेश को Pid के माध्यम से spawned प्रक्रिया में भेजा जाता है! संदेश आदेश।

उपरोक्त कार्यक्रम का आउटपुट है -

उत्पादन

Area of the Rectangle is 60

प्रक्रियाओं की अधिकतम संख्या

समसामयिकता में, सिस्टम पर अधिकतम अनुमत प्रक्रियाओं को निर्धारित करना महत्वपूर्ण है। फिर आपको यह समझने में सक्षम होना चाहिए कि एक सिस्टम पर कितनी प्रक्रिया समवर्ती रूप से निष्पादित हो सकती है।

आइए एक उदाहरण देखें कि हम यह कैसे निर्धारित कर सकते हैं कि अधिकतम प्रक्रिया क्या है जो एक सिस्टम पर निष्पादित हो सकती है।

-module(helloworld). 
-export([max/1,start/0]). 

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)]. 

start()->
   max(1000), 
   max(100000).

किसी भी मशीन पर, जिसमें एक अच्छी प्रसंस्करण शक्ति है, दोनों उपरोक्त अधिकतम फ़ंक्शन पास करेंगे। उपरोक्त कार्यक्रम से एक नमूना आउटपुट निम्नलिखित है।

Maximum allowed processes:262144
Process spawn time=47.0 (16.0) microseconds
Maximum allowed processes:262144
Process spawn time=12.81 (10.15) microseconds

टाइमआउट के साथ प्राप्त करें

कभी-कभी एक प्राप्त कथन एक संदेश के लिए हमेशा के लिए प्रतीक्षा कर सकता है जो कभी नहीं आता है। यह कई कारणों से हो सकता है। उदाहरण के लिए, हमारे कार्यक्रम में कोई तार्किक त्रुटि हो सकती है, या जो प्रक्रिया हमें संदेश भेजने जा रही है, वह संदेश भेजने से पहले क्रैश हो सकती है। इस समस्या से बचने के लिए, हम प्राप्त स्टेटमेंट में एक टाइमआउट जोड़ सकते हैं। यह एक अधिकतम समय निर्धारित करता है कि प्रक्रिया एक संदेश प्राप्त करने के लिए इंतजार करेगी।

निर्दिष्ट टाइमआउट के साथ प्राप्त संदेश का सिंटैक्स निम्नलिखित है

वाक्य - विन्यास

receive 
Pattern1 [when Guard1] -> 
Expressions1; 

Pattern2 [when Guard2] ->
Expressions2; 
... 
after Time -> 
Expressions 
end

सबसे सरल उदाहरण एक स्लीपर फ़ंक्शन बनाना है जैसा कि निम्नलिखित कार्यक्रम में दिखाया गया है।

उदाहरण

-module(helloworld). 
-export([sleep/1,start/0]). 

sleep(T) ->
   receive 
   after T -> 
      true 
   end. 
   
start()->
   sleep(1000).

उपरोक्त कोड वास्तव में बाहर निकलने से पहले 1000 एमएस के लिए सो जाएगा।

चयनात्मक प्राप्त

Erlang में प्रत्येक प्रक्रिया में एक संबद्ध मेलबॉक्स है। जब आप प्रक्रिया को संदेश भेजते हैं, तो संदेश को मेलबॉक्स में डाल दिया जाता है। इस मेलबॉक्स की जांच केवल उसी समय की जाती है जब आपका प्रोग्राम एक प्राप्त विवरण का मूल्यांकन करता है।

निम्नलिखित चयनात्मक प्राप्त बयान का सामान्य सिंटैक्स है।

वाक्य - विन्यास

receive 
Pattern1 [when Guard1] ->
Expressions1; 

Pattern2 [when Guard1] ->
Expressions1; 
... 
after 
Time ->
ExpressionTimeout 
end

इस प्रकार उपरोक्त कथन काम करता है -

  • जब हम एक प्राप्त बयान दर्ज करते हैं, तो हम एक टाइमर शुरू करते हैं (लेकिन केवल तभी जब एक अनुभाग अभिव्यक्ति में मौजूद है)।

  • मेलबॉक्स में पहला संदेश लें और इसे पैटर्न 1, पैटर्न 2 और इसी तरह से मिलान करने का प्रयास करें। यदि मैच सफल होता है, तो संदेश मेलबॉक्स से हटा दिया जाता है, और पैटर्न के बाद के भावों का मूल्यांकन किया जाता है।

  • यदि प्राप्त स्टेटमेंट में कोई भी पैटर्न मेलबॉक्स में पहले संदेश से मेल नहीं खाता है, तो पहला संदेश मेलबॉक्स से हटा दिया जाता है और "सेव कतार" में डाल दिया जाता है। मेलबॉक्स में दूसरा संदेश तब आजमाया जाता है। यह प्रक्रिया तब तक दोहराई जाती है जब तक कि एक मेल संदेश नहीं मिलता है या जब तक मेलबॉक्स के सभी संदेशों की जांच नहीं हो जाती है।

  • यदि मेलबॉक्स में कोई भी संदेश मेल नहीं खाता है, तो प्रक्रिया को निलंबित कर दिया जाता है और अगली बार मेलबॉक्स में एक नया संदेश डालने पर निष्पादन के लिए पुनर्निर्धारित किया जाएगा। ध्यान दें कि जब कोई नया संदेश आता है, तो बचाने के लिए कतार में संदेश प्रेषित नहीं होते हैं; केवल नए संदेश का मिलान किया जाता है।

  • जैसे ही किसी संदेश का मिलान किया गया, तो सभी संदेश जो कतार में सहेजे गए हैं, मेलबॉक्स में पुन: दर्ज किए जाते हैं, जिस क्रम में वे प्रक्रिया में आए थे। यदि एक टाइमर सेट किया गया था, तो यह साफ हो गया है।

  • यदि हम संदेश का इंतजार कर रहे हैं, तो टाइमर समाप्त हो जाता है, तो अभिव्यक्तियों का मूल्यांकन करें ExpressionsTimeout और किसी भी सहेजे गए संदेश को मेलबॉक्स में वापस उसी क्रम में डालें, जिस क्रम में वे प्रक्रिया में पहुंचे थे।