Sobes.tech
Middle+

Ako sa pracuje s vláknami (threads) a úlohami (tasks), ak na ne odkazuje viacero z nich na spoločný stav?

sobes.tech AI

Odpoveď od AI

Pre bezpečný prístup k zdieľanému stavu v prostredí s viacerými vláknami sa používajú mechanizmy synchronizácie.

Hlavné prístupy:

  • Zámky: lock je najrozšírenejší mechanizmus. Zabezpečuje výlučný prístup k bloku kódu alebo objektu pre jedno vlákno naraz. Mutex (vzájomné vylúčenie) sa tiež používa, ale často pri komunikácii medzi procesmi.
  • Semantiky: Obmedzujú počet vlákien, ktoré môžu súčasne získať prístup k zdroju.
  • Monitor: Predstavuje výkonnejšiu verziu lock, ktorá umožňuje vláknam čakať na oznámenia od iných vlákien.
  • ReadWriteLock: Umožňuje viacerým vláknam čítať dáta súčasne, ale len jednému písať.
  • Atómové operácie: Pre jednoduché operácie (inkrement, dekrement, porovnanie-výmena) je možné použiť statické metódy triedy Interlocked.

Pri práci s úlohami (Tasks), najmä s async/await, je dôležité si uvedomiť, že úlohy nie sú viazané na konkrétne vlákno. Kontexte synchronizácie (SynchronizationContext) pomáhajú vrátiť sa do požadovaného kontextu (napríklad, UI vlákno) po dokončení asynchrónnej operácie.

Príklad použitia lock:

// Objekt na zámok
private readonly object _lockObject = new object();
private int _sharedCounter = 0;

public void IncrementCounter()
{
    // Zámok prístupu ku spoločnému čítaču
    lock (_lockObject)
    {
        _sharedCounter++;
    }
}

Príklad použitia Interlocked:

private int _sharedAtomicCounter = 0;

public void IncrementAtomicCounter()
{
    // Atomické zvýšenie
    Interlocked.Increment(ref _sharedCounter);
}