jeudi 24 février 2022

Behaviour of threads using conditional variables

Im trying to solve producent-consumer problem with conditional variables and I met a strange behaviour of my program. I was trying to understand it but I need some help. The program which I wrote shows that sometimes the state variable goes over desired value, here 10. I need exactly 10 values. I think that this depends on the random delay time. How could I manage my problem?

#include <iostream>
#include <thread>
#include <mutex>
#include <random>
#include <queue>
#include <fstream>
#include <sstream>
#include <condition_variable>

void producer_task(std::mutex& buff_mtx, int& state, std::condition_variable& cv){
    while(1){
        // simulate delay of reading data from sensor
        static thread_local std::mt19937 generator(0);
        std::uniform_int_distribution<int> sleep_distribution(100,5000);
        std::this_thread::sleep_for(std::chrono::milliseconds(sleep_distribution(generator)));
        {
            std::lock_guard<std::mutex> lk_guard(buff_mtx);
            // add data to buffor
            state++;
        }
        cv.notify_all();
    }
}

void consumer_task(std::mutex& buff_mtx, int& state, std::condition_variable& cv){
    while(1){
        std::unique_lock<std::mutex> lk_guard(buff_mtx);
        cv.wait(lk_guard, [&state](){std::cout << state << std::endl; return state == 10;});
        state = 0;
        // after there is state == 10, print 10 readings from buffer
    }
}

int main(){
    std::vector<std::thread> threads;
    std::mutex buff_mtx;
    std::condition_variable cv;
    int state = 0;
    for(int i = 0; i < 5; i++){
        threads.emplace_back(producer_task,std::ref(buff_mtx),std::ref(state), std::ref(cv));
    }
    threads.emplace_back(consumer_task,std::ref(buff_mtx),std::ref(state), std::ref(cv));
    for(auto& thread : threads){
        thread.join();
    }
}

Aucun commentaire:

Enregistrer un commentaire