Golang এর Concurrency পর্ব -1

আমি যখন Golang শিখতে শুরু করি, তখন গো রুটিন (goroutine) নিয়ে বেশ সমস্যায় পড়েছিলাম। অনেক সময় বুঝলেও পরে ভুলে যেতাম। এরপর আমি চেষ্টা করলাম ভিতর থেকে বিষয়টি ভালোভাবে বোঝার। এই লেখায় আমি যেভাবে শিখেছি, তার অভিজ্ঞতা তুলে ধরবো।

প্রথম ধাপ: প্রসেস ও থ্রেড বোঝা

একটি প্রোগ্রাম যখন কম্পিউটারে চলে, তখন তাকে প্রসেস বলা হয়। আর সেই প্রসেসের ভেতরে ছোট ছোট কাজ করতে পারে এমন অংশকে থ্রেড বলে।

উদাহরণ:

যখন আপনি Chrome ব্রাউজার চালান, তখন এটি একটি প্রসেস।

এর ভেতরের প্রতিটি ট্যাব হলো থ্রেড, যা আলাদাভাবে কাজ করে।

যেমন, একটি অফিসে (প্রসেস) একাধিক কর্মী (থ্রেড) একসঙ্গে কাজ করতে পারে।

কনটেক্সট সুইচিং

একটি CPU কোর একই সময়ে দুটি প্রোগ্রাম (প্রসেস) চালাতে পারে না। তাই একটার কাজ কিছুক্ষণ চালিয়ে, সেটিকে সাময়িক থামিয়ে অন্যটায় সুইচ করে। পরে আবার আগেরটায় ফিরে আসে।

এটি অনেকটা এরকম: আপনি একবার গণিত পড়ছেন → পরে ইংরেজি পড়তে বসলেন → তারপর আবার গণিতে ফিরে গেলেন।

প্রতিবার প্রসেস পরিবর্তনের সময় কিছু সময় নষ্ট হয়, যাকে কনটেক্সট সুইচিং ওভারহেড বলে। কারণ CPU-কে প্রতিবার আগের প্রসেসের অবস্থা সংরক্ষণ (save) করে পরে পুনরুদ্ধার (restore) করতে হয়।

আবার অনেক সময় দেখা যায় একই ডেটা দুটো প্রোগ্রাম একই সাথে এই মেমোরী বা রিসোর্স এ্যাকসেস করার ট্রাই করছে যেটা ডেডলক হয়ে যাচ্ছে। মানে ধরি একটা বই একই সাথে আমি ও আপনি দুজনে নেওয়ার ট্রাই করবো, কিন্তু আমি বা আপনি কেউ নিতে পারবো না! এটাই ডেডলক। যাই হোক এই সমস্যা থেকে বের হবার জন্য একটা নিয়ম হলো আগে যেই যাবে সেই আগে নিবে। মানে মেমোরী বা রিসোর্স ডেটা অ্যাকসেস করার সময় গার্ডের ব্যবস্থা করা হলো। মানে যখন আপনি রিসোর্স নিতে যাবে তখন আপনি লক করবেন তার ডেটা নেওয়া শেষ হলে আনলক করবেন। ফলে আপনার ডেটা অ্যাকসেস নেওয়ার সময় তেমন সমস্যা হবে না। এক্ষেত্রে একই সময়ে দুটো প্রোগ্রাম চললে তারা একই রিসোর্স বা মেমোরী শেয়ার করে, লক-আনলক পদ্বতি ব্যবহার। কিন্তু সেক্ষেত্রে একই সময়ে দুজন ডেটা বা রিসোর্স ব্যবহার করছে গেলে কেউ একজন লক-আনলক ঠিকমত ব্যবহার না করলে ডেটা ডেডলক, লাইভলক তৈরি হতে পারে।

ডেডলক ও লাইভলক

ডেডলক:

ধরুন, একটি বই আপনি ও আপনার বন্ধু দুজনেই নিতে চাইছেন, কিন্তু কেউই বইটি নিতে পারছেন না! এটি ডেডলক।

সমাধান: যে আগে আসবে, সে আগে পাবে — এই নিয়ম মেনে চলা।

প্রোগ্রামিংয়ে, এটি লক-আনলক (Lock-Unlock) মেকানিজম দিয়ে সমাধান করা হয়।

লাইভলক:

দুজনই যদি একে অপরকে জায়গা দিতে চায়, কিন্তু কেউই এগোতে না পারে, তাহলে সেটি লাইভলক। যেমন, আপনি ও আপনার বন্ধু একই দরজায় দাঁড়িয়ে, দুজনেই একে অপরকে যেতে দিচ্ছেন, কিন্তু কেউই পার হচ্ছেন না!

CSP (Communicating Sequential Processes)

কম্পিউটার বিজ্ঞানী টনি হোয়ার (Tony Hoare) ১৯৭৮ সালে CSP ধারণা দেন। এখানে প্রোগ্রামগুলো একই মেমোরি বা রিসোর্স শেয়ার না করে বরং চ্যানেলের (Channel) মাধ্যমে যোগাযোগ করে।

ধরি, দুটো প্রোগ্রাম চলছে এবং তারা একই মেমেরী এ্যাকসেস করার চেষ্টা না করে তারা একটা পাইপ বানিয়েছে সেই পাইপের মাধ্যমে তারা ডেটা বা রিসোর্স আদান-প্রদান করে

ধরুন, একটি রেস্টুরেন্টে কয়েকজন ওয়েটার কাজ করছে। তারা প্রত্যেকে আলাদাভাবে খাবার পরিবেশন করছে, কিন্তু একই ট্রেতে খাবার পরিবেশন না করে একে অপরের সঙ্গে সমন্বয় করছে।

ঠিক একইভাবে, Golang-এ goroutine ও channel CSP ধারণার উপর ভিত্তি করে তৈরি।

Goroutine ও Channel

Goroutine হলো হালকা ওজনের থ্রেড, যা কম মেমোরি ও কম কনটেক্সট সুইচিং ওভারহেড ব্যবহার করে। Channel ব্যবহার করে goroutine-রা একে অপরের সাথে তথ্য আদান-প্রদান করতে পারে, যাতে ডেডলক বা রিসোর্স কনফ্লিক্ট না হয়।

পরের পর্বগুলোতে গোশিডিউলার, গো রুটিন সহ এগুলো নিয়ে আলোচনা করা হবে।

উপসংহার

গো রুটিন ও চ্যানেল ব্যবহারের মাধ্যমে আমরা একই মেমোরি শেয়ার না করেও সমান্তরাল প্রোগ্রামিং (concurrent programming) করতে পারি। এটি ডেডলক, লাইভলক ও কনটেক্সট সুইচিং ওভারহেড কমিয়ে দেয়, যা আমাদের প্রোগ্রামকে আরও কার্যকরী করে তোলে।

Comments