Sobes.tech
Middle

İplər arasında qarşılıqlı əlaqəni necə sinxronlaşdırmaq olar?

sobes.tech Süni İntellekt

AI-dan cavab

C++-də çox əsas sinxronizasiya mexanizmləri mövcuddur:

  • Mutexlər: Bir vaxtda yalnız bir axın mutexə sahib ola bilər. Ümumi resursların eyni vaxtda istifadəsini qarşısını almaq üçün istifadə olunur.

    #include <mutex>
    
    std::mutex myMutex;
    
    void criticalSection() {
        std::lock_guard<std::mutex> lock(myMutex); // Mutexin ələ alınması
        // Ümumi resursla işləmək
    } // Mutex avtomatik olaraq sərhəd daxilindən çıxarkən azad edilir
    
  • Semaforlar: Məhdud sayda resursa girişə nəzarət edir. Semafor sayğacı mövcud resursların sayını göstərir. Axınlar sayğacı azaldır (resurs əldə etmək üçün) və artırır (azad etmək üçün).

    #include <semaphore.h> // Adətən POSIX sistemlərində istifadə olunur
    
    sem_t mySemaphore;
    
    void initSemaphore(int count) {
        sem_init(&mySemaphore, 0, count); // Sayğacı count ilə ilkinləşdirir
    }
    
    void acquireResource() {
        sem_wait(&mySemaphore); // Sayğacı azaldır, 0 olarsa bloklanır
        // Resursdan istifadə
    }
    
    void releaseResource() {
        sem_post(&mySemaphore); // Sayğacı artırır
    }
    
  • Şərt dəyişənləri: Axınların müəyyən bir şərti gözləməsinə imkan verir. Adətən mutexlərlə birlikdə istifadə olunur. Şərti gözləyən axın mutexi azad edir və digər axın şərtin yerinə yetirilməsini xəbər verənə qədər bloklanır.

    #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(); // Bir gözləyən axını xəbərdar edir
    }
    
    int consumer() {
        std::unique_lock<std::mutex> lock(myMutex);
        myCondition.wait(lock, [&]{ return !myQueue.empty(); }); // Şərtin gözlənilməsi
        int value = myQueue.front();
        myQueue.pop();
        return value;
    }
    
  • Atomar dəyişən bayraqları: Sadə əməliyyatların (oxuma, yazma, dəyişdirmə) atomar şəkildə yerinə yetirilməsinə imkan verir, bu əməliyyatlar üçün mutex istifadə etməyə ehtiyac yoxdur.

    #include <atomic>
    
    std::atomic_int atomicCounter(0);
    
    void incrementCounter() {
        atomicCounter++; // Atomik artırma
    }
    
  • Barajlar: Bir neçə axını sinxronizasiya edir ki, heç biri barajdan keçmədən əvvəl hamısı oraya çatmalıdır.

    #include <barrier> // C++20
    
    std::barrier myBarrier(3); // 3 axın üçün baraj
    
    void workerThread() {
        // İşin bir hissəsini yerinə yetirmək
        myBarrier.arrive_and_wait(); // Hamı barajda gözləyir
        // Növbəti iş hissəsini yerinə yetirmək
    }
    

Xüsusi mexanizmin seçimi axınlar arasındakı qarşılıqlı əlaqənin xarakterindən asılıdır:

  • Mutexlər: Ümumi məlumatların qorunmasında ən çox istifadə olunan üsul.
  • Semaforlar: Məhdud sayda resursa girişə nəzarət.
  • Şərt dəyişənləri: Axının müəyyən bir hadisə və ya vəziyyətin baş verməsini gözləməsi.
  • Atomar dəyişənlər: Sadə, atomar əməliyyatların effektiv yerinə yetirilməsi.
  • Barajlar: Axınların növbəti mərhələyə keçməsini sinxronizasiya edir.