Kako sinhronizovati interakciju između niti?
Одговор од АИ
sobes.tech АИ
Постоји неколико основних механизама за синхронизацију и интеракцију између нити у C/C++:
-
Мутекси (Mutexes): Обезбеђују ексклузиван приступ заједничком ресурсу. Нит која је стекла мутекс блокира друге нитке које покушавају да га стекну док га не ослободи.
#include <mutex> std::mutex my_mutex; void my_thread_function() { my_mutex.lock(); // Стекнути мутекс // Рад са заједничким ресурсом my_mutex.unlock(); // Ослободити мутекс }Или са RAII:
#include <mutex> #include <lock_guard> std::mutex my_mutex; void my_thread_function() { std::lock_guard<std::mutex> lock(my_mutex); // Стекнути мутекс при креирању објекта // Рад са заједничким ресурсом // Мутекс ће се аутоматски ослободити при изласку из области видљивости } -
Семафори (Semaphores): Обједињење мутекса. Одржава бројач који дозвољава одређеном броју нитки да истовремено приступе ресурсу.
#include <semaphore.h> // За POSIX семафоре #include <windows.h> // За Windows семафоре sem_t my_semaphore; // POSIX семафор void my_thread_function() { sem_wait(&my_semaphore); // Смањити бројач семафора, блокирати ако је 0 // Рад са ресурсом sem_post(&my_semaphore); // Повећати бројач семафора }(Напомена: Стандардни C++ не укључује директно семафоре, али су доступни преко системских библиотека или трећих страна.)
-
Условне променљиве (Condition Variables): Користе се да нит може да чека на одређени услов, при чему ослобађа мутекс. Друга нит може обавестити чекајућу да је услов испуњен.
#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; }); // Чекање на испуњење услова // Услови су испуњени, рад са ресурсом } void notifying_thread() { std::unique_lock<std::mutex> lock(my_mutex); condition_met = true; lock.unlock(); // Ослобађање мутекса пре обавештења (препоручљиво) my_cv.notify_one(); // Обавештавање једне чекајуће нитке // или // my_cv.notify_all(); // Обавештавање свих чекајућих нитки } -
Атомарне операције (Atomic Operations): Омогућавају извођење једноставних операција над променљивим (нпр. инкремент, декремент) као једне недељиве акције, без потребе за експлицитним закључавањем мутекса.
#include <atomic> std::atomic<int> counter(0); void my_thread_function() { counter++; // Атомски инкремент // Или: // counter.fetch_add(1); } -
Делимични закључавања (Shared Mutexes): Омогућавају више нитки да читају податке истовремено, али само једна да пише.
#include <shared_mutex> // C++17 и више std::shared_mutex my_shared_mutex; void read_thread() { my_shared_mutex.lock_shared(); // Закључавање за читање // Читање података my_shared_mutex.unlock_shared(); // Ослобађање за читање } void write_thread() { my_shared_mutex.lock(); // Закључавање за писање (ексклузивно) // Писање података my_shared_mutex.unlock(); // Ослобађање за писање } -
Баријере (Barriers): Омогућавају групи нитки да чекају док све не достигну одређену тачку у свом извршењу, пре него што наставе.
#include <barrier> // C++20 std::barrier sync_point(4); // Бариера за 4 нитке void my_thread_function() { // Рад пре баријере sync_point.arrive_and_wait(); // Чекање док све нитке не достигну баријеру // Рад после баријере }
Избор конкретног механизма зависи од природе интеракције и делених ресурса.