Kuidas saab sünkroniseerida niitide vahelist suhtlust?
sobes.tech AI
Vastus AI-lt
C++-s ir vairāki galvenie mehānismi pavedienu sinhronizācijai:
-
Mutexes (Mutexes): nodrošina izņēmumu. Tik viens pavediens var piederēt mutexam vienlaikus. Izmanto kopēju resursu aizsardzībai pret vienlaicīgu piekļuvi.
#include <mutex> std::mutex myMutex; void criticalSection() { std::lock_guard<std::mutex> lock(myMutex); // mutex ieguve // Darbs ar kopēju resursu } // mutex automātiski atbrīvojas, izejot no apgabala -
Semafori (Semaphores): pārvalda piekļuvi ierobežotam resursu skaitam. Semafors ir skaitītājs, kas norāda pieejamo resursu skaitu. Pavedieni samazina skaitītāju (resursa iegūšanai) un palielina (resursa atbrīvošanai).
#include <semaphore.h> // bieži lieto POSIX sistēmās sem_t mySemaphore; void initSemaphore(int count) { sem_init(&mySemaphore, 0, count); // semafora inicializācija ar skaitītāju count } void acquireResource() { sem_wait(&mySemaphore); // skaitītāja samazināšana, bloku, ja 0 // Resursa izmantošana } void releaseResource() { sem_post(&mySemaphore); // skaitītāja palielināšana } -
Nosacījumu mainīgie (Condition Variables): ļauj pavedieniem gaidīt noteiktu nosacījumu. Parasti lieto kopā ar mutexiem. Gaidīšanas pavediens atbrīvo mutexu un bloķējas, kamēr cits pavediens to nebrīdina par nosacījuma izpildi.
#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(); // paziņojums vienam gaidīgam pavedienam } int consumer() { std::unique_lock<std::mutex> lock(myMutex); myCondition.wait(lock, [&]{ return !myQueue.empty(); }); // nosacījuma gaidīšana int value = myQueue.front(); myQueue.pop(); return value; } -
Atomālie mainīgie (Atomic Variables): ļauj veikt vienkāršas operācijas (lasīšana, rakstīšana, modifikācija) atomiski, bez nepieciešamības lietot mutexus šīm konkrētajām operācijām.
#include <atomic> std::atomic_int atomicCounter(0); void incrementCounter() { atomicCounter++; // atomiska palielināšana } -
Barjeras (Barriers): sinhronizē vairākus pavedienus tā, lai neviens no tiem nevar turpināt izpildi, kamēr visi ne sasniedz barjeru.
#include <barrier> // C++20 std::barrier myBarrier(3); // barjera trim pavedieniem void workerThread() { // Darba daļas izpilde myBarrier.arrive_and_wait(); // gaidīt visus pavedienus pie barjeras // Nākamās darba daļas izpilde }
Izvēle ir atkarīga no saskarsmes rakstura starp pavedieniem:
- Mutexi: visbiežāk izmantots kopēju datu aizsardzībai.
- Semafori: pārvalda piekļuvi ierobežotam resursu skaitam.
- Nosacījumu mainīgie: gaida noteiktu notikumu vai stāvokli.
- Atomālie mainīgie: efektīva vienkāršu, atomisku operāciju izpilde.
- Barjeras: pavedienu sinhronizācija, lai pārietu uz nākamo posmu.