Sobes.tech
Middle+

Cum se gestionează lucrul cu firele (threads) și sarcinile (tasks) atunci când mai multe dintre ele accesează o stare comună?

sobes.tech AI

Răspuns de la AI

Pentru a accesa în mod sigur starea partajată într-un mediu multi-thread, se utilizează mecanisme de sincronizare.

Abordări principale:

  • Blocări: lock este cel mai răspândit mecanism. Asigură accesul exclusiv la un bloc de cod sau obiect pentru un singur fir de execuție o dată. Mutex (excludere reciprocă) este, de asemenea, utilizat, dar adesea în interacțiunea între procese.
  • Semantici: Limitează numărul de fire de execuție care pot accesa simultan o resursă.
  • Monitor: Reprezintă o versiune mai puternică a lock, permițând firelor de execuție să aștepte notificări de la altele.
  • ReadWriteLock: Permite mai multor fire de execuție să citească datele în același timp, dar doar unuia să scrie.
  • Operații atomice: Pentru operații simple (incrementare, decrementare, comparație-schimbare), se pot folosi metode statice ale clasei Interlocked.

Atunci când lucrați cu sarcini (Tasks), în special cu async/await, este important să vă amintiți că sarcinile nu sunt legate de un fir de execuție specific. Contextele de sincronizare (SynchronizationContext) ajută la revenirea în contextul necesar (de exemplu, firul UI) după finalizarea unei operațiuni asincrone.

Exemplu de utilizare a lock:

// Obiect pentru blocare
private readonly object _lockObject = new object();
private int _sharedCounter = 0;

public void IncrementCounter()
{
    // Blocarea accesului la contorul partajat
    lock (_lockObject)
    {
        _sharedCounter++;
    }
}

Exemplu de utilizare a Interlocked:

private int _sharedAtomicCounter = 0;

public void IncrementAtomicCounter()
{
    // Incrementare atomică
    Interlocked.Increment(ref _sharedAtomicCounter);
}