Sobes.tech
Middle+

Jak se pracuje s vlákny (threads) a úkoly (tasks), pokud na ně odkazuje více z nich na společný stav?

sobes.tech AI

Odpověď od AI

Pro bezpečný přístup ke sdílenému stavu v prostředí s více vlákny se používají mechanismy synchronizace.

Hlavní přístupy:

  • Zámky: lock je nejrozšířenější mechanismus. Zajišťuje výlučný přístup ke kódu nebo objektu pro jedno vlákno najednou. Mutex (vzájemné vyloučení) se také používá, ale často při komunikaci mezi procesy.
  • Semantiky: Omezují počet vláken, která mohou současně získat přístup k prostředku.
  • Monitor: Představuje výkonnější verzi lock, která umožňuje vláknům čekat na oznámení od jiných vláken.
  • ReadWriteLock: Umožňuje více vláknům číst data současně, ale pouze jedno vlákno může psát.
  • Atomické operace: Pro jednoduché operace (inkrement, dekrement, porovnání-výměna) lze použít statické metody třídy Interlocked.

Při práci s úkoly (Tasks), zejména s async/await, je důležité pamatovat, že úkoly nejsou vázány na konkrétní vlákno. Synchronizační kontexty (SynchronizationContext) pomáhají vrátit se do požadovaného kontextu (například UI vlákno) po dokončení asynchronní operace.

Příklad použití lock:

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

public void IncrementCounter()
{
    // Zamkne přístup ke sdílenému čítači
    lock (_lockObject)
    {
        _sharedCounter++;
    }
}

Příklad použití Interlocked:

private int _sharedAtomicCounter = 0;

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