সি# এ থ্রেড সিঙ্ক্রোনাইজেশন এমন একটি প্রক্রিয়া, যার মাধ্যমে একাধিক থ্রেড একই রিসোর্সে সমান্তরালে অ্যাক্সেস করতে চায় এমন সময়ে ডেটা ইনকনসিস্টেন্সি রোধ করা যায়। এটি মূলত থ্রেড সেফটি নিশ্চিত করে, যাতে একই সময়ে কেবলমাত্র একটি থ্রেড নির্দিষ্ট রিসোর্স বা কোড ব্লক এক্সেস করতে পারে।
থ্রেড সিঙ্ক্রোনাইজেশনের চাহিদা
যখন একাধিক থ্রেড একই রিসোর্স বা ডেটা শেয়ার করে এবং তা পরিবর্তন করতে চায়, তখন ডেটা ইনকনসিস্টেন্সি বা "race condition" হতে পারে। এই সমস্যাগুলি দূর করতে সিঙ্ক্রোনাইজেশন প্রয়োজন হয়।
সি# এ থ্রেড সিঙ্ক্রোনাইজেশনের উপায়
সি# এ থ্রেড সিঙ্ক্রোনাইজেশনের জন্য বিভিন্ন টুলস রয়েছে। এর মধ্যে কয়েকটি সাধারণ টুল হলো:
- lock কিওয়ার্ড
- Monitor ক্লাস
- Mutex ক্লাস
- Semaphore ক্লাস
১. lock কিওয়ার্ড
lock কিওয়ার্ড সাধারণত থ্রেড সিঙ্ক্রোনাইজেশনের সবচেয়ে সহজ উপায় হিসেবে ব্যবহৃত হয়। এটি একটি নির্দিষ্ট কোড ব্লককে একবারে কেবলমাত্র একটি থ্রেডের জন্য অ্যাক্সেসযোগ্য করে।
using System;
using System.Threading;
public class Program
{
private static readonly object lockObj = new object();
public static void PrintNumbers()
{
lock (lockObj)
{
for (int i = 1; i <= 5; i++)
{
Console.WriteLine(i);
Thread.Sleep(500);
}
}
}
public static void Main()
{
Thread thread1 = new Thread(PrintNumbers);
Thread thread2 = new Thread(PrintNumbers);
thread1.Start();
thread2.Start();
}
}
ব্যাখ্যা
- lockObj: একটি অবজেক্ট যা
lockব্লকে ব্যবহার করা হয়। এটি একবারে কেবল একটি থ্রেডকেPrintNumbersমেথড অ্যাক্সেস করতে দেয়। - lock (lockObj): এই ব্লকটিতে একবারে কেবলমাত্র একটি থ্রেড প্রবেশ করতে পারে। অন্য থ্রেডকে অপেক্ষা করতে হয় যতক্ষণ না প্রথম থ্রেড কাজ শেষ করে।
২. Monitor ক্লাস
Monitor ক্লাস lock এর মতো কাজ করে, তবে এটি বেশি নিয়ন্ত্রণ দেয়। Monitor.Enter একটি কোড ব্লককে লক করে এবং Monitor.Exit দিয়ে লক মুক্ত করে।
using System;
using System.Threading;
public class Program
{
private static readonly object lockObj = new object();
public static void PrintNumbers()
{
Monitor.Enter(lockObj);
try
{
for (int i = 1; i <= 5; i++)
{
Console.WriteLine(i);
Thread.Sleep(500);
}
}
finally
{
Monitor.Exit(lockObj);
}
}
public static void Main()
{
Thread thread1 = new Thread(PrintNumbers);
Thread thread2 = new Thread(PrintNumbers);
thread1.Start();
thread2.Start();
}
}
ব্যাখ্যা
- Monitor.Enter(lockObj):
lockObjঅবজেক্ট লক করে। - Monitor.Exit(lockObj):
lockObjঅবজেক্টের লক মুক্ত করে। - try-finally ব্লক:
Monitor.Exitঅবশ্যই চালানোর জন্যfinallyব্লক ব্যবহার করা হয়।
৩. Mutex (Mutual Exclusion)
Mutex একাধিক প্রক্রিয়া থেকে অ্যাক্সেস নিয়ন্ত্রণের জন্য ব্যবহৃত হয়। এটি lock বা Monitor থেকে বেশি কার্যকর, কারণ এটি কম্পিউটারের বিভিন্ন প্রক্রিয়ায় ব্যবহারযোগ্য।
using System;
using System.Threading;
public class Program
{
private static Mutex mutex = new Mutex();
public static void PrintNumbers()
{
mutex.WaitOne(); // Mutex লক করা
try
{
for (int i = 1; i <= 5; i++)
{
Console.WriteLine(i);
Thread.Sleep(500);
}
}
finally
{
mutex.ReleaseMutex(); // Mutex মুক্ত করা
}
}
public static void Main()
{
Thread thread1 = new Thread(PrintNumbers);
Thread thread2 = new Thread(PrintNumbers);
thread1.Start();
thread2.Start();
}
}
ব্যাখ্যা
- WaitOne(): এটি থ্রেডকে মিউটেক্স লক করতে বলে এবং অন্য থ্রেডকে অপেক্ষা করতে দেয়।
- ReleaseMutex(): মিউটেক্স মুক্ত করে, যাতে অন্য থ্রেড এটিকে অ্যাক্সেস করতে পারে।
Mutexএকাধিক প্রক্রিয়া বা অ্যাপ্লিকেশন থেকে শেয়ার্ড রিসোর্স সিঙ্ক্রোনাইজ করতে সহায়ক।
৪. Semaphore
Semaphore একবারে একাধিক থ্রেডকে নির্দিষ্ট রিসোর্সে প্রবেশের অনুমতি দেয়। উদাহরণস্বরূপ, আপনি চাইলে একই সময়ে দুইটি থ্রেডকে কাজ করতে দিতে পারেন, তবে তৃতীয় থ্রেডকে অপেক্ষা করাতে পারেন যতক্ষণ না অন্য দুটি থ্রেড কাজ শেষ করে।
using System;
using System.Threading;
public class Program
{
// একসাথে ২টি থ্রেড প্রবেশের অনুমতি
private static Semaphore semaphore = new Semaphore(2, 2);
public static void PrintNumbers()
{
semaphore.WaitOne(); // Semaphore লক করা
try
{
for (int i = 1; i <= 5; i++)
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId + " - " + i);
Thread.Sleep(500);
}
}
finally
{
semaphore.Release(); // Semaphore মুক্ত করা
}
}
public static void Main()
{
Thread thread1 = new Thread(PrintNumbers);
Thread thread2 = new Thread(PrintNumbers);
Thread thread3 = new Thread(PrintNumbers);
thread1.Start();
thread2.Start();
thread3.Start();
}
}
ব্যাখ্যা
new Semaphore(2, 2):Semaphoreএকসাথে ২টি থ্রেডকে অ্যাক্সেসের অনুমতি দেয়।- WaitOne(): Semaphore লক করে এবং অন্য থ্রেডকে অপেক্ষা করতে বলে।
- Release(): Semaphore মুক্ত করে, যাতে অন্য থ্রেড রিসোর্সে প্রবেশ করতে পারে।
সংক্ষেপে থ্রেড সিঙ্ক্রোনাইজেশন
- lock: সহজ ও কার্যকর উপায়; একবারে একটি থ্রেডকে রিসোর্সে অ্যাক্সেস করতে দেয়।
- Monitor:
lockএর মতোই তবে এটি বেশি নিয়ন্ত্রণ দেয়, যেমনEnterএবংExitমেথড। - Mutex: কম্পিউটারের বিভিন্ন প্রক্রিয়ায় ব্যবহার করা যায় এবং একাধিক অ্যাপ্লিকেশনের মধ্যে রিসোর্স সিঙ্ক্রোনাইজ করতে সাহায্য করে।
- Semaphore: একসাথে নির্দিষ্ট সংখ্যক থ্রেডকে রিসোর্সে প্রবেশের অনুমতি দেয়।
সি# এ থ্রেড সিঙ্ক্রোনাইজেশন ব্যবহার করে একাধিক থ্রেডের মধ্যে শেয়ার্ড রিসোর্স ব্যবহারে সংঘাত বা ডেটা ইনকনসিস্টেন্সি এড়ানো যায় এবং প্রোগ্রামকে সঠিকভাবে পরিচালনা করা সম্ভব হয়।