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:
lockje 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);
}