Elixir-এ সব কোডই প্রসেসের ভেতরে চলে।
ডিফল্টভাবে, একটি ফাংশন যে প্রসেস থেকে কল করা হয়েছিল, সেটিতেই এক্সিকিউট হয়। যখন আপনাকে স্পষ্টভাবে কোনো একটি ফাংশন নতুন একটি প্রসেসে রান করতে হবে, তখন spawn/1 ব্যবহার করুন:
spawn(fn -> 2 + 2 end)
# => #PID<0.125.0>
spawn/1 একটি নতুন প্রসেস তৈরি করে, যা প্রদত্ত 0-arity ফাংশনটি এক্সিকিউট করে এবং একটি প্রসেস আইডেন্টিফায়ার (PID) রিটার্ন করে। ফাংশনটি যতক্ষণ এক্সিকিউট হয়, নতুন প্রসেসটি ততক্ষণ জীবিত থাকে, তারপর নিঃশব্দে এক্সিট করে।
Elixir-এর প্রসেসকে অপারেটিং সিস্টেমের প্রসেসের সাথে গুলিয়ে ফেলা উচিত নয়। Elixir-এর প্রসেস অনেক কম মেমোরি ও CPU ব্যবহার করে। Elixir-এর এমন অ্যাপ্লিকেশন থাকা সম্পূর্ণ স্বাভাবিক, যেগুলো শত শত Elixir প্রসেস চালায়।
প্রসেসগুলো সরাসরি একে অন্যের সাথে তথ্য শেয়ার করে না। ডেটা শেয়ার করার জন্য প্রসেসগুলো মেসেজ পাঠায় ও গ্রহণ করে।
আপনি send/2 দিয়ে যেকোনো প্রসেসে একটি মেসেজ পাঠাতে পারেন। send/2-এর প্রথম আর্গুমেন্ট হলো প্রাপকের PID, দ্বিতীয় আর্গুমেন্ট হলো মেসেজটি।
একটি মেসেজ যেকোনো টাইপের হতে পারে। প্রায়ই এটি অ্যাটম ও টিউপল নিয়ে গঠিত হয়। আপনি যদি কোনো রেসপন্স পেতে চান, তাহলে মেসেজের কোথাও প্রেরকের PID যোগ করা উচিত। আপনি self() দিয়ে বর্তমান প্রসেসের PID পেতে পারেন।
send/2 যাচাই করে না যে প্রাপক মেসেজটি পেয়েছে কি না, কিংবা প্রাপক এখনও জীবিত আছে কি না। মেসেজটি প্রাপকের মেইলবক্সে জমা হয়, এবং প্রাপক স্পষ্টভাবে মেসেজ গ্রহণ করতে চাইলেই কেবল সেটি পড়া হয়।
receive/1 ম্যাক্রো ব্যবহার করে মেইলবক্স থেকে একটি মেসেজ পড়া যায়। এটি একটি do ব্লক নেয়, যা মেসেজগুলোর উপর প্যাটার্ন ম্যাচ করতে পারে।
receive do
{:ping, sender_pid} -> send(sender_pid, :pong)
:do_nothing -> nil
end
receive/1 মেইলবক্স থেকে প্রদত্ত যেকোনো প্যাটার্নের সাথে মেলে এমন একটি মেসেজ নেবে এবং সেই প্যাটার্নের জন্য দেওয়া এক্সপ্রেশনটি এক্সিকিউট করবে। মেইলবক্সে যদি কোনো মেসেজ না থাকে, বা মেইলবক্সের কোনো মেসেজই কোনো প্যাটার্নের সাথে না মেলে, তাহলে receive/1 একটি মেসেজের জন্য অপেক্ষা করবে।
আপনি যদি একাধিক মেসেজ পেতে চান, তাহলে receive/1 রিকার্সিভভাবে কল করতে হবে। একটি রিকার্সিভ ফাংশন তৈরি করা একটি কমন প্যাটার্ন, যার নাম হতে পারে loop, যা receive/1 কল করে, মেসেজটি নিয়ে কিছু করে, তারপর আরও মেসেজের জন্য অপেক্ষা করতে নিজেকে আবার কল করে। একটি receive/1 কল থেকে আরেকটিতে যদি কিছু স্টেট বহন করতে হয়, তাহলে সেই loop ফাংশনে একটি আর্গুমেন্ট পাস করে তা করতে পারেন।
প্রসেস আইডেন্টিফায়ার হলো আলাদা একটি ডেটা টাইপ। এগুলো মেইলবক্স অ্যাড্রেস হিসেবে কাজ করে। কোনো প্রসেসের PID থাকলে আপনি সেই প্রসেসে একটি মেসেজ পাঠাতে পারেন। PID সাধারণত পরোক্ষভাবে তৈরি হয়, নতুন প্রসেস তৈরি করে এমন ফাংশনের রিটার্ন ভ্যালু হিসেবে, যেমন spawn।
আপনি একটি Take-A-Number মেশিনের জন্য একটি এমবেডেড সিস্টেম লিখছেন। এটি খুবই সরল একটি মডেল। এটি পরপর নম্বর দিতে পারে এবং সর্বশেষ কোন নম্বর দেওয়া হয়েছিল তা জানাতে পারে।
start/0 ফাংশনটি ইমপ্লিমেন্ট করুন। এটি একটি নতুন প্রসেস তৈরি করবে এবং সেই প্রসেসের PID রিটার্ন করবে। নতুন প্রসেসটিকে এখনো কিছুই করতে হবে না।
TakeANumber.start()
# => #PID<0.138.0>
মনে রাখবেন, এই কোডটি প্রতিবার চালালে PID ভিন্ন হতে পারে।
মেশিনটি এমনভাবে পরিবর্তন করুন যাতে নতুন তৈরি হওয়া প্রসেসটি মেসেজ গ্রহণের জন্য প্রস্তুত থাকে (একটি রিসিভ লুপ শুরু করুন) এবং তার প্রাথমিক অবস্থা হয় 0। এটি {:report_state, sender_pid} মেসেজ গ্রহণ করতে পারবে। এই মেসেজগুলোর উত্তরে এটি তার বর্তমান অবস্থা (সর্বশেষ দেওয়া টিকিট নম্বর) sender_pid-কে পাঠাবে এবং তারপর আরও মেসেজের জন্য অপেক্ষা করবে।
machine_pid = TakeANumber.start()
# a client sending a message to the machine
send(machine_pid, {:report_state, self()})
# a client receiving a message from the machine
receive do
msg -> msg
end
# => 0
মেশিনটি এমনভাবে পরিবর্তন করুন যাতে এটি {:take_a_number, sender_pid} মেসেজ গ্রহণ করতে পারে। এটি তার অবস্থা ১ বাড়াবে, নতুন অবস্থাটি sender_pid-কে পাঠাবে এবং তারপর আরও মেসেজের জন্য অপেক্ষা করবে।
machine_pid = TakeANumber.start()
# a client sending a message to the machine
send(machine_pid, {:take_a_number, self()})
# a client receiving a message from the machine
receive do
msg -> msg
end
# => 1
মেশিনটি এমনভাবে পরিবর্তন করুন যাতে এটি একটি :stop মেসেজ গ্রহণ করতে পারে। এটি আরও মেসেজের জন্য অপেক্ষা করা বন্ধ করবে।
মেশিনটি এমনভাবে পরিবর্তন করুন যাতে কোনো অপ্রত্যাশিত মেসেজ পেলে এটি সেটি উপেক্ষা করে এবং আরও মেসেজের জন্য অপেক্ষা করতে থাকে।
Exercism-এ সাইন আপ করুন, Elixir ট্র্যাকের 58টি কনসেপ্ট168টি অনুশীলনী আর সত্যিকারের মানুষের মেন্টরিং দিয়ে শিখুন ও দক্ষ হয়ে উঠুন, সম্পূর্ণ বিনামূল্যে।