Ako synchronizovať interakciu medzi vláknami?
sobes.tech AI
Odpoveď od AI
Existuje niekoľko základných mechanizmov synchronizácie vlákien v C++:
-
Mutexy: Zabezpečujú vzájomné vylúčenie. Len jedno vlákno môže vlastniť mutex v danom okamihu. Používajú sa na ochranu spoločných zdrojov pred súčasným prístupom.
#include <mutex> std::mutex myMutex; void criticalSection() { std::lock_guard<std::mutex> lock(myMutex); // Zámok mutexu // Práca so spoločným zdrojom } // Mutex sa automaticky uvoľní pri opustení rozsahu -
Semafory: Riadi prístup k obmedzenému počtu zdrojov. Semafor má čítač, ktorý ukazuje počet dostupných zdrojov. Vlákna znižujú (získanie zdroja) a zvyšujú (uvoľnenie zdroja) tento čítač.
#include <semaphore.h> // Bežne sa používa v POSIX systémoch sem_t mySemaphore; void initSemaphore(int count) { sem_init(&mySemaphore, 0, count); // Inicializácia semaforu s čítačom count } void acquireResource() { sem_wait(&mySemaphore); // Zníženie čítača, blokovanie pri 0 // Použitie zdroja } void releaseResource() { sem_post(&mySemaphore); // Zvýšenie čítača } -
Podmienkové premenné: Umožňujú vláknam čakať na určitý stav. Obvykle sa používajú spolu s mutexmi. Vlákno čakajúce na podmienku uvoľní mutex a zablokuje sa, kým ho iné vlákno ne upozorní na splnenie podmienky.
#include <condition_variable> #include <mutex> #include <queue> std::condition_variable myCondition; std::mutex myMutex; std::queue<int> myQueue; void producer(int value) { std::lock_guard<std::mutex> lock(myMutex); myQueue.push(value); myCondition.notify_one(); // Upozornenie na jedno čakajúce vlákno } int consumer() { std::unique_lock<std::mutex> lock(myMutex); myCondition.wait(lock, [&]{ return !myQueue.empty(); }); // Čakanie na podmienku int value = myQueue.front(); myQueue.pop(); return value; } -
Atomické premenné: Umožňujú vykonávať jednoduché operácie (čítanie, zápis, modifikácia) atomicky, bez potreby použitia mutexov pre tieto operácie.
#include <atomic> std::atomic_int atomicCounter(0); void incrementCounter() { atomicCounter++; // Atomické zvýšenie } -
Barriéry: Synchronizujú niekoľko vlákien tak, aby žiadne nemohlo pokračovať vo vykonávaní, kým všetky nedosiahnu bariéru.
#include <barrier> // C++20 std::barrier myBarrier(3); // Bariéra pre 3 vlákna void workerThread() { // Vykonanie časti práce myBarrier.arrive_and_wait(); // Čakanie na všetky vlákna na bariére // Vykonanie ďalšej časti práce }
Výber konkrétneho mechanizmu závisí od charakteru interakcie medzi vláknami:
- Mutexy: Najbežnejší spôsob ochrany spoločných dát.
- Semafory: Riadenie prístupu k obmedzeným zdrojom.
- Podmienkové premenné: Čakanie vlákna na určitú udalosť alebo stav.
- Atomické premenné: Efektívne vykonávanie jednoduchých, atomických operácií.
- Barriéry: Synchronizácia vlákien pre spoločný prechod na ďalší krok.