Kā var sinhronizēt pavedienu mijiedarbību?
sobes.tech AI
Atbilde no AI
Ir daudz galveno mehānismu, kas tiek izmantoti saskarnes sinhronizācijai starp pavedieniem C/C++:
-
Mutexi (Mutexes): Nodrošina ekskluzīvu piekļuvi koplietotajam resursam. Pavediens, kas iegūst mutex, bloķē citus pavedienus, kas mēģina to iegūt, līdz tas tiek atbrīvots.
#include <mutex> std::mutex my_mutex; void my_thread_function() { my_mutex.lock(); // Iegūt mutex // Darbs ar koplietoto resursu my_mutex.unlock(); // Atbrīvot mutex }Vai ar RAII:
#include <mutex> #include <lock_guard> std::mutex my_mutex; void my_thread_function() { std::lock_guard<std::mutex> lock(my_mutex); // Iegūt mutex, izveidojot objektu // Darbs ar koplietoto resursu // Mutex automātiski atbrīvojas, izejot no apgabala } -
Semafori (Semaphores): Mūsdienu versija mutexiem. Uztur skaitītāju, kas ļauj noteiktam skaitam pavedienu vienlaikus piekļūt resursam.
#include <semaphore.h> // POSIX semafori #include <windows.h> // Windows semafori sem_t my_semaphore; // POSIX semafors void my_thread_function() { sem_wait(&my_semaphore); // Samazina semafora skaitītāju, bloķē, ja tas ir 0 // Darbs ar resursu sem_post(&my_semaphore); // Palielina semafora skaitītāju }(Piezīme: Standarta C++ tieši neietver semaforus, bet tie ir pieejami caur sistēmas bibliotēkām vai trešo pušu realizācijām)
-
Nosacījuma mainīgie (Condition Variables): Tiek izmantoti, lai pavediens varētu gaidīt noteikta nosacījuma iestāšanos, vienlaikus atbrīvojot mutex. Cits pavediens var paziņot, ka nosacījums ir izpildīts.
#include <mutex> #include <condition_variable> std::mutex my_mutex; std::condition_variable my_cv; bool condition_met = false; void waiting_thread() { std::unique_lock<std::mutex> lock(my_mutex); my_cv.wait(lock, []{ return condition_met; }); // Gaidīt nosacījuma izpildi // Nosacījums izpildīts, darbs ar resursu } void notifying_thread() { std::unique_lock<std::mutex> lock(my_mutex); condition_met = true; lock.unlock(); // Atbrīvot mutex pirms paziņojuma (ieteicams) my_cv.notify_one(); // Paziņot vienam gaidošajam pavedienam // vai // my_cv.notify_all(); // Paziņot visiem gaidošajiem pavedieniem } -
Atomāras operācijas (Atomic Operations): Ļauj veikt vienkāršas operācijas ar mainīgajiem (piemēram, inkrementu, dekrementu) kā vienotu, nedalāmu darbību, nerequīrējot mutex bloķēšanu.
#include <atomic> std::atomic<int> counter(0); void my_thread_function() { counter++; // Atomārs inkrementācija // vai: // counter.fetch_add(1); } -
Lasīšanas un rakstīšanas slēdzenes (Shared Mutexes): Atļauj vairākiem pavedieniem lasīt datus vienlaikus, bet tikai vienam rakstīt.
#include <shared_mutex> // C++17 un jaunākas versijas std::shared_mutex my_shared_mutex; void read_thread() { my_shared_mutex.lock_shared(); // Iegūt lasīšanai // Lasīt datus my_shared_mutex.unlock_shared(); // Atbrīvot lasīšanai } void write_thread() { my_shared_mutex.lock(); // Iegūt rakstīšanai (ekskluzīvi) // Rakstīt datus my_shared_mutex.unlock(); // Atbrīvot rakstīšanai } -
Barjeras (Barriers): Atļauj grupai pavedienu gaidīt, līdz visi sasniedz noteiktu punktu savā izpildē, pirms turpināt.
#include <barrier> // C++20 std::barrier sync_point(4); // Barjera 4 pavedieniem void my_thread_function() { // Darbs pirms barjeras sync_point.arrive_and_wait(); // Gaidīt, līdz visi sasniedz barjeru // Darbs pēc barjeras }
Izvēle konkrētam mehānismam ir atkarīga no mijiedarbības rakstura un koplietojamiem resursiem.