Elixir में सारा कोड प्रोसेस के अंदर चलता है। Elixir के प्रोसेस:
डिफॉल्ट रूप से एक फंक्शन उसी प्रोसेस में चलता है जिसमें उसे कॉल किया गया था। जब आपको किसी खास फंक्शन को नए प्रोसेस में साफ़-साफ़ चलाना हो, तो spawn का इस्तेमाल कीजिए:
spawn/1 ऐसा फंक्शन लेता है जिसे वह सीधे चलाता है।
spawn(fn -> 2 + 2 end)
# => #PID<0.125.0>
spawn/3 ऐसा फंक्शन लेता है जिसे वह मॉड्यूल के नाम, फंक्शन के नाम (एटम के रूप में) और उस फंक्शन को दिए जाने वाले आर्गुमेंट के ऐरे की मदद से चलाता है।
spawn(String, :split, ["hello there", " "])
# => #PID<0.113.0>
जैसे ही किसी प्रोसेस का फंक्शन चलना पूरा होता है, वह प्रोसेस बंद हो जाता है।
आप Process.alive?/1 की मदद से देख सकते हैं कि कोई प्रोसेस अब भी जीवित (यानी चल रहा) है या नहीं:
pid = spawn(fn -> 2 + 2 end)
Process.alive?(pid)
# => false
प्रोसेस आपस में सीधे जानकारी साझा नहीं करते। डेटा साझा करने के लिए प्रोसेस एक-दूसरे को संदेश भेजते हैं। कोड को साथ-साथ चलाने के इस तरीके को एक्टर मॉडल कहते हैं।
send/2 की मदद से किसी प्रोसेस को संदेश भेजिए।
send(pid, :hello)
send यह नहीं जाँचता कि संदेश मिला या नहीं, और न ही यह कि पाने वाला प्रोसेस अब भी जीवित है या नहीं।संदेश किसी भी टाइप का हो सकता है।
मौजूदा प्रोसेस को भेजा गया संदेश आप receive/1 की मदद से पा सकते हैं।
receive तब तक इंतज़ार करता है जब तक किसी भी दिए गए पैटर्न से मेल खाता कोई संदेश प्रोसेस की मेलबॉक्स में न आ जाए।
after ब्लॉक की मदद से इसे एक टाइमआउट दिया जा सकता है।receive/1 में एक ऐसा _ क्लॉज़ ज़रूर लिखिए जो हर संदेश को पकड़ ले, ताकि बिना पढ़े संदेश जमा होने से मेमोरी खत्म न हो जाए।receive do
{:ping, sender_pid} -> send(sender_pid, :pong)
_ -> nil
after
5000 ->
{:error, "No message in 5 seconds"}
end
अगर आपको एक से ज़्यादा संदेश पाने हैं, तो आपको receive/1 को रीकर्सिव तरीके से कॉल करना होगा। एक आम तरीका यह है कि एक रीकर्सिव फंक्शन बनाया जाए, जैसे loop नाम का, जो receive/1 को कॉल करता है, संदेश के साथ कुछ करता है, और फिर और संदेशों का इंतज़ार करने के लिए खुद को कॉल करता है। अगर आपको एक receive/1 कॉल से दूसरी कॉल तक कुछ स्थिति ले जानी है, तो आप उस loop फंक्शन को एक आर्गुमेंट देकर ऐसा कर सकते हैं।
def loop(state) do
receive do
:increment_by_one ->
loop(state + 1)
{:report_state, sender_pid} ->
send(sender_pid, state)
loop(state)
:stop ->
nil
_ ->
loop(state)
end
end
व्यवहार में यह तरीका सीधे शायद ही कभी इस्तेमाल किया जाता है। Elixir में कोड को साथ-साथ चलाने के लिए कुछ ऐब्स्ट्रैक्शन मिलते हैं, जैसे Agent मॉड्यूल या GenServer बिहेवियर, जो दोनों रिसीव लूप के ऊपर बने हैं। लेकिन इन ऐब्स्ट्रैक्शन का कुशलता से इस्तेमाल कर पाने के लिए इन बुनियादी बातों को समझना बहुत ज़रूरी है।