কম্পিউটার টিউটোরিয়াল

C/C++-তে প্রসেস সিনক্রোনাইজেশন (Process Synchronization)

প্রসেস সিনক্রোনাইজেশন (Process Synchronization) হল শেয়ার্ড ডেটা (shared data)-এ কনকারেন্ট এক্সেস (concurrent access) এর সমস্যা কাটাতে একটি টেকনিক যা ডেটা ইনকনসিস্টেন্সি (data inconsistency)-র ফলাফল হতে পারে। একটি কোঅপারেটিং প্রসেস (cooperating process) হল সেটি যা অন্য প্রসেসকে প্রভাবিত করতে পারে বা অন্য প্রসেস দ্বারা প্রভাবিত হতে পারে যা প্রসেসের ডেটা-তে ইনকনসিস্টেন্সি ল্যাড করে, তাই ডেটার কনসিস্টেন্সির জন্য প্রসেস সিনক্রোনাইজেশন প্রয়োজন।

দ ক্রিটিক্যাল-সেকশন প্রোব্লেম (The Critical-Section Problem)

প্রতিটি প্রসেসের একটি রিজার্ভড কোড সেগমেন্ট (reserved segment of code) থাকে যাকে ক্রিটিক্যাল সেকশন (Critical Section) বলা হয়। এই সেকশনে, প্রসেস কমন ভেরিয়েবল পরিবর্তন করতে পারে, টেবিল আপডেট করতে পারে, ফাইল লিখতে পারে, ইত্যাদি। ক্রিটিক্যাল সেকশন সম্পর্কে মূল কথা হলো যখন একটি প্রসেস তার ক্রিটিক্যাল সেকশনে এক্সিকিউট করছে, তখন অন্য কোনো প্রসেস তার ক্রিটিক্যাল সেকশনে এক্সিকিউট করতে পারবে না। প্রতিটি প্রসেসকে তার ক্রিটিক্যাল সেকশনে ঢুকতে পারমিশন চাইতে হবে এবং এই রিকোয়েস্ট ইমপ্লিমেন্ট করার কোড সেকশন হল এন্ট্রি সেকশন (Entry Section), কোডের শেষ হল এক্সিট সেকশন (Exit Section) এবং বাকি কোড হল রিমেইনডার সেকশন (remainder section)।

একটি নির্দিষ্ট প্রসেস P1-এর ক্রিটিক্যাল সেকশনের স্ট্রাকচার নিচে দেওয়া হলো:

C/C++-তে প্রসেস সিনক্রোনাইজেশন (Process Synchronization)

ক্রিটিক্যাল সেকশনের জন্য তিনটি রিকোয়ারমেন্ট (requirements) পূরণ করা বাধ্যতামূলক:

  • মিউচুয়াল এক্সক্লুশন (Mutual Exclusion) − যদি একটি প্রসেস (যেমন P1) তার ক্রিটিক্যাল সেকশনে এক্সিকিউট করছে, তবে অন্য যেকোনো প্রসেস (যেমন P2) তার ক্রিটিক্যাল সেকশনে এক্সিকিউট করতে পারবে না।
  • প্রগ্রেস (Progress) − যদি কোনো প্রসেস তার ক্রিটিক্যাল সেকশনে এক্সিকিউট না করছে থাকে এবং এমন প্রসেস থাকে যারা তার ক্রিটিক্যাল সেকশনে ঢুকতে চায়, তবে শুধু যেসব প্রসেস তাদের রিমেইনডার সেকশনে এক্সিকিউট করছে না সেসব প্রসেসই ক্রিটিক্যাল সেকশনে ঢুকতে রিকোয়েস্ট করতে পারবে এবং সিলেকশনটি অনির্দিষ্ট কালের জন্য পোস্টপোন (postponed) করা যাবে না।
  • বাউন্ডেড ওয়েইটিং (Bounded Waiting) − বাউন্ডেড ওয়েইটিং-এ, একটি প্রসেস তার ক্রিটিক্যাল সেকশনে ঢুকতে রিকোয়েস্ট করার পর এবং সেই রিকোয়েস্ট গ্রান্ট (granted) হওয়ার আগে সে কতবার তার ক্রিটিক্যাল সেকশনে ঢুকতে পারে সেটার একটি লিমিট বা বাউন্ড (limit/bound) থাকে।

অপারেটিং সিস্টেমে ক্রিটিক্যাল সেকশন হ্যান্ডল করার জন্য দুটি সাধারণ অ্যাপ্রোচ ব্যবহৃত হয়:

  • প্রিপ্টিভ 커নেল (Preemptive Kernel) − একটি প্রিপ্টিভ কर्नেল একটি প্রসেসকে প্রিপ্ট (preempt) করতে দেয় যখন সেটি কার্নেল মোড (kernel mode)-এ রান করছে।
  • নন-প্রিপ্টিভ কर्नেল (Non-Preemptive Kernels) − একটি নন-প্রিপ্টিভ কার্নেল কার্নেল মোড-এ রান করা একটি প্রসেসকে প্রিপ্ট করতে দেয় না।

পিটারসন'স সলিউশন (Peterson's Solution)

পিটারসন'স সলিউশন (Peterson's Solution) হল ক্রিটিক্যাল-সেকশন প্রোব্লেমের একটি ক্লাসিক সফটওয়্যার বেসড সমাধান। এটি দুটি প্রসেসের জন্য সীমাবদ্ধ যারা তাদের ক্রিটিক্যাল সেকশন এবং রিমেইনডার সেকশন এর মাঝে এক্সিকিউশন অল্টারনেট (alternate) করে। পিটারসন'স সলিউশন দুটি ডেটা আইটেম শেয়ার করার প্রয়োজন دو প্রসেসের মাঝে:

  • int turn;
  • boolean flag[2];

এখানে, turn ভেরিয়েবল নির্দেশ করে কার বাড়ি (turn) ক্রিটিক্যাল সেকশনে ঢুকতে। flag অ্যারে নির্দেশ করে প্রসেসটি তার ক্রিটিক্যাল সেকশনে ঢুকতে রেডি (ready) কিনা।

যদি turn == i হয়, তবে মানে প্রসেস Pi-কে তার ক্রিটিক্যাল সেকশনে ঢুকতে দেওয়া হয়েছে।

যদি flag[j] TRUE হয়, তবে মানে প্রসেস j তার ক্রিটিক্যাল সেকশনে ঢুকতে রেডি।

পিটারসন'স সলিউশনে প্রসেস P-এর স্ট্রাকচার নিচে দেওয়া হলো:

C/C++-তে প্রসেস সিনক্রোনাইজেশন (Process Synchronization)

পিটারসন'স সলিউশন সব তিনটি কন্ডিশন সংরক্ষণ করে:

  • মিউচুয়াল এক্সক্লুশন − একবারে একটি প্রসেসই ক্রিটিক্যাল সেকশন এক্সেস করতে পারে।
  • প্রগ্রেস − ক্রিটিক্যাল সেকশনের বাইরে থাকা একটি প্রসেস অন্য প্রসেসকে ক্রিটিক্যাল সেকশনে ঢুকতে ব্লক করে না।
  • বাউন্ডেড ওয়েইটিং − প্রতিটি প্রসেস অনির্দিষ্ট কাল ধরে অপেক্ষা না করে তার ক্রিটিক্যাল সেকশনে ঢুকতে পারবে।

সিনক্রোনাইজেশন হার্ডওয়্যার (Synchronization Hardware)

এটি দুটি টাইপের ইনস্ট্রাকশন (instructions) ব্যবহার করে ইমপ্লিমেন্ট করা হয়:

  • Test and Set()
  • swap()

Test and Set() সিনক্রোনাইজেশনের সমস্যা সমাধানের একটি হার্ডওয়্যার সমাধান। এতে একটি শেয়ার্ড ভেরিয়েবল থাকে যাকে একাধিক প্রসেস শেয়ার করে যা Lock নামে পরিচিত যা ০ এবং ১ থেকে একটি মান নিতে পারে যেখানে ১ মানে লক অর্জিত (Lock gained) এবং ০ মানে লক রিলিজড (Lock released)।

যখন প্রসেসগুলো তাদের ক্রিটিক্যাল সেকশনে ঢুকতে চায়, তারা লকের ভ্যালু জানতে চায়। যদি লকের ভ্যালু ১ হয়, তবে তারা অপেক্ষা করতে হয় যতক্ষণ না লকের ভ্যালু ০ হয়ে যায়।

TestAndSet() দিয়ে মিউচুয়াল-এক্সক্লুশন ইমপ্লিমেন্টেশন নিচে দেওয়া হলো:

C/C++-তে প্রসেস সিনক্রোনাইজেশন (Process Synchronization)

সেমাফোর (Semaphores)

সেমাফোর (Semaphore) হল একটি সিনক্রোনাইজেশন টুল (synchronization tool) যা TestAndSet() এবং Swap() ইনস্ট্রাকশন দ্বারা জেনারেটেড সমস্যা কাটাতে ব্যবহৃত হয়। একটি সেমাফোর S হল একটি ইন্টিজার ভেরিয়েবল যা দুটি স্ট্যান্ডার্ড অ্যাটমিক (atomic) অপারেশন দিয়ে অ্যাক্সেস করা যায়: wait() এবং signal()।

wait() ফাংশন:

wait(S) {
    while S <= 0
        ; // no operation
    S--;
}

signal() ফাংশন:

signal(S) {
    S++;
}

যখন একটি প্রসেস সেমাফোরের ভ্যালু মডিফাই (modify) করছে, তখন অন্য কোনো প্রসেস সিমালটেনিয়াসলি (simultaneously) একই সেমাফোরের ভ্যালু ম্যানিপুলেট (manipulate) করতে পারবে না।

সেমাফোর দিয়ে মিউচুয়াল-এক্সক্লুশন ইমপ্লিমেন্টেশন নিচে দেওয়া হলো:

C/C++-তে প্রসেস সিনক্রোনাইজেশন (Process Synchronization)

অপারেটিং সিস্টেম দুটি টাইপের সেমাফোর ব্যবহার করে:

  • কাউন্টিং সেমাফোর (Counting Semaphore) − এই টাইপের সেমাফোরের ভ্যালু অন্রেস্ট্রিক্টেড ডোমেন (unrestricted domain)-এ घूमতে পারে।
  • বাইনারি সেমাফোর (Binary Semaphore) − এই টাইপের সেমাফোরের ভ্যালু ০ এবং ১ এর মাঝে ঘूमতে পারে। এদের মিউটেক্স লক (Mutex Locks)-ও বলা হয়। অপারেটিং সিস্টেম এই ব্যবহার করে মাল্টিপল প্রসেসে ক্রিটিক্যাল সেকশন ইস্যু রিজল্ভ করতে।
  1. C/C++-তে putwchar() ফাংশন

  2. C/C++-তে memcpy() ফাংশন

  3. AA ট্রি: C/C++-তে ব্যালেন্সড ট্রি ডেটা স্ট্রাকচার

  4. C/C++-এ strcpy() ফাংশন