Sobes.tech
Middle+

C#-da bir neçə axın ümumi vəziyyətə müraciət etdikdə, iş parçaları və tapşırıqlarla necə işləyir?

sobes.tech Süni İntellekt

AI-dan cavab

C#-də ümumi vəziyyətlə işləyərkən çoxlu axınlar arasında sinxronizasiya problemləri və yarış vəziyyətləri yaranır. İstifadə olunan mexanizmlər bunlardır:

  1. Bloklama (Locking):

    • lock operatoru istifadə olunur ki, bu da tənha bir axının resursa girişini təmin edən kritik bölmə yaradır.
    • Sinxronizasiya üçün adətən private readonly object kimi bir obyekt istifadə olunur.
    // Lock istifadə nümunəsi
    private readonly object _lockObject = new object();
    private int _sharedCounter = 0;
    
    public void IncrementCounter()
    {
        lock (_lockObject)
        {
            _sharedCounter++; // Kritik bölmə
        }
    }
    
  2. Atomik əməliyyatlar:

    • System.Threading.Interlocked sinfi atomik əməliyyatlar təmin edir (məsələn, Increment, Decrement, Add, Exchange), bunlar çoxlu axın təhlükəsizdir və açıq bloklama olmadan əməliyyatları yerinə yetirir.
    // Interlocked istifadə nümunəsi
    private volatile int _sharedValue = 0; // dəyişikliklərin görünməsi üçün volatile
    
    public void UpdateValue(int newValue)
    {
        Interlocked.Exchange(ref _sharedValue, newValue); // Atomik təyin etmə
    }
    
    public void IncrementValue()
    {
         Interlocked.Increment(ref _sharedValue); // Atomik artırma
    }
    
    • volatile dəyişikliklərin görünməsini təmin etsə də, çoxaddımlı əməliyyatların atomikliyini təmin etmir. Atomik əməliyyatlar üçün Interlocked istifadə olunmalıdır.
  3. System.ThreadingSystem.Threading.Tasks-dən sinxronizasiya sinifləri:

    • Monitor: lock-a nisbətən daha aşağı səviyyəli bloklama mexanizmi.
    • Mutex: bir neçə proses arasında resursa girişin sinxronizasiyası üçün.
    • SemaphoreSlim: eyni zamanda resursa giriş edə biləcək axınların sayını məhdudlaşdırır.
    • ReaderWriterLockSlim: çoxlu axınların eyni zamanda oxumağa, lakin yalnız birinin yazmağa imkan verir.
  4. Axın təhlükəsiz kolleksiyalar:

    • System.Collections.Concurrent ad alanı, ConcurrentBag<T>, ConcurrentDictionary<TKey, TValue>, ConcurrentQueue<T>, ConcurrentStack<T> kimi kolleksiyaları ehtiva edir və çoxlu axınla istifadə üçün xüsusi hazırlanmışdır. Bu kolleksiyaların istifadəsi əsas əməliyyatlarda əl ilə sinxronizasiyaya ehtiyac qalmır.
    // `ConcurrentDictionary` istifadə nümunəsi
    private ConcurrentDictionary<string, int> _sharedData = new ConcurrentDictionary<string, int>();
    
    public void AddOrUpdateData(string key, int value)
    {
        _sharedData.AddOrUpdate(key, value, (k, oldValue) => oldValue + value);
    }
    
  5. Dəyişməz obyektlər (Immutable objects):

    • Dəyişməz obyektlərin yaradılması, onların vəziyyətinin dəyişdirilə bilməməsi deməkdir. Əgər ümumi vəziyyət dəyişməz obyektlə təmsil olunursa, çoxlu axınlar onu təhlükəsiz şəkildə oxuya bilər və yeniləmək üçün yeni nümunə yaradılır.

Task Parallel Library (TPL) ilə işləyərkən də ümumi vəziyyətə girişdə sinxronizasiyaya diqqət yetirmək lazımdır. TPL paralel əməliyyatların yaradılması və idarə olunmasını asanlaşdırır, lakin ümumi məlumatlarla işləyərkən təhlükəsizlik təminatı sizin məsuliyyətinizdədir.

Uyğun sinxronizasiya mexanizminin seçimi konkret tapşırıq və ümumi vəziyyətə giriş xüsusiyyətlərindən asılıdır.