Kaip galima sinchronizuoti tarpų sąveiką?
sobes.tech AI
Atsakymas iš AI
C++ yra keli pagrindiniai mechanizmai srautų sinchronizacijai:
-
MUTEX'ai (Mutexes): užtikrina išimtį. Tik vienas srautas gali turėti mutex'ą bet kuriuo metu. Naudojami bendriems ištekliams apsaugoti nuo vienalaikio prieigos.
#include <mutex> std::mutex myMutex; void criticalSection() { std::lock_guard<std::mutex> lock(myMutex); // užfiksuoti mutex'ą // Darbas su bendru ištekliu } // mutex'as automatiškai atlaisvinamas išeinant iš apimties -
Semaforai (Semaphores): valdo prieigą prie riboto kiekio išteklių. Semaforas turi skaitiklį, kuris nurodo prieinamų išteklių skaičių. Srautai mažina skaitiklį (gaudami išteklių) ir didina (atlaisvindami).
#include <semaphore.h> // dažnai naudojama POSIX sistemose sem_t mySemaphore; void initSemaphore(int count) { sem_init(&mySemaphore, 0, count); // semaforo inicijavimas su skaitikliu count } void acquireResource() { sem_wait(&mySemaphore); // sumažinti skaitiklį, blokuoti jei 0 // Išteklio naudojimas } void releaseResource() { sem_post(&mySemaphore); // padidinti skaitiklį } -
Sąlygos kintamieji (Condition Variables): leidžia srautams laukti tam tikro sąlygos. Paprastai naudojami kartu su mutex'ais. Laukiantis srautas atlaisvina mutex'ą ir blokuojasi, kol kitas srautas jį informuos apie sąlygos įvykdymą.
#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(); // pranešimas vienam laukiančiam srautui } int consumer() { std::unique_lock<std::mutex> lock(myMutex); myCondition.wait(lock, [&]{ return !myQueue.empty(); }); // sąlygos laukimas int value = myQueue.front(); myQueue.pop(); return value; } -
Atominių kintamųjų (Atomic Variables): leidžia atlikti paprastus veiksmus (skaityti, rašyti, modifikuoti) atominiu būdu, nereikalaujant naudoti mutex'ų šiems konkretiems veiksmams.
#include <atomic> std::atomic_int atomicCounter(0); void incrementCounter() { atomicCounter++; // atominis didinimas } -
Barjerai (Barriers): sinchronizuoja kelis srautus taip, kad nė vienas jų negali tęsti vykdymo, kol visi nepasieks barjero.
#include <barrier> // C++20 std::barrier myBarrier(3); // barjeras trims srautams void workerThread() { // Darbo dalies vykdymas myBarrier.arrive_and_wait(); // laukia visų srautų prie barjero // Sekančios darbo dalies vykdymas }
Pasirinkimas priklauso nuo srautų sąveikos pobūdžio:
- MUTEX'ai: dažniausiai naudojamas bendriems duomenims apsaugoti.
- Semaforai: valdo prieigą prie riboto kiekio išteklių.
- Sąlygos kintamieji: laukia tam tikro įvykio ar būsenos.
- Atominiai kintamieji: efektyvus paprastų, atominių operacijų vykdymas.
- Barjerai: srautų sinchronizavimas siekiant pereiti į kitą etapą.