Создание поточно-ориентированного ранжирования и его слушателя в c ++ - PullRequest
0 голосов
/ 20 июня 2020

Мой профессор C ++ дал нам упражнение, чтобы попрактиковаться в потокобезопасных структурах в C ++.

Это упражнение:

Создайте поточно-безопасный класс, который управляет рейтингом онлайн-игры: каждому игроку назначается псевдоним и счет. Создается метод для вставки игрока (или обновления его оценки, если он уже присутствует), в то время как другой метод создается для блокировки вызывающего его потока при ожидании изменения в рейтинге (слушатель).

Вот что я сделал:

class Classifica{
    std::map<std::string,int> grad;
    int nlistener=0;
    std::mutex gm;
    std::condition_variable didUpdate;
    std::atomic<bool> variation = false;

public:

    void insert(std::string nickname, int punteggio){ // every time i update i set the flag 
        int found = 0;
        //take control
        std::lock_guard<std::mutex> lg(gm);
        // see if already present
        std::map<std::string, int>::iterator it;
        for (it = grad.begin();it != grad.end(); it++){
            if (it->first == nickname)
                found = 1;
        }

        if (found == 1){
            if ( punteggio > grad[nickname])
                grad[nickname] = punteggio;
        } else {
            grad.insert({nickname, punteggio});
        }

        // Notify update
        variation = true;
        didUpdate.notify_all();
    }

    void listener(){ //blocks thread
        std::unique_lock<std::mutex> ug(gm);
        nlistener++;
        while (!variation){
            didUpdate.wait(ug);
        }
        // ok variation happend i can unblock
        nlistener--;
        std::cout << "Variation happened" << std::endl;
        if (nlistener == 0){
            variation = false;
        }
    }
};

int main(){
    Classifica myclass;
    std::thread list1([&myclass] { myclass.listener(); });
    std::thread ins1([&myclass] { myclass.insert("fede1",4); });
    std::thread ins2([&myclass] { myclass.insert("fede2",4); });
    std::thread list2([&myclass] { myclass.listener(); });
    std::thread list3([&myclass] { myclass.listener(); });
    std::thread ins3([&myclass] { myclass.insert("fede3",4); });

    list2.join();
    list3.join();
    ins3.join();
    list1.join();
    ins1.join();
    ins2.join();
    return 0;

}

Проблема в том, что иногда программа не заканчивается, и я не могу понять, в чем проблема.

Может ли это быть в том, как потоки вызываются в основном?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...