Потоки с одинаковыми аргументами дают разные значения

У меня проблема, когда два потока с разными функциями и объектами с одинаковым аргументом приводят к разным значениям для этих объектов.

Для уточнения, пожалуйста, соблюдайте следующий код:

class Player(){
    // Definition of Player here
    // with get- and set functions
    // for a certain value.
}

class Game(){
    static void Draw(Player p){
        while(1){
            gotoxy(p.getValue(), 15);
            cout << p.name();
       }
    }

    static void Move(Player p){
        int x = p.getValue();
        while(1){
            if(_kbhit()){
                p.setValue(++x);
            }
        }
    }

    void startGame(){
        Player pl1(5);

        thread thd1(Move, pl1);
        thread thd2(Draw, pl1);
        thd1.join();
        thd2.join();
    }  

}

В то время как значение 'x' изменяется в функции 'Move' для каждого нажатия клавиши, при получении этого значения в функции 'Draw' все еще имеет начальное значение для 'pl1' (которое равно 5).

Как я могу получить "Draw", чтобы получить то же значение, что и "Move"? Я ценю любую помощь и руководство.

Заранее спасибо!

2 ответа

Решение

Вы передаете игрока по значению

static void Move(Player pl)

а не по ссылке / указателю, поэтому обе функции имеют свои собственные локальные копии исходной переменной.

static void Move(Player& pl)

возьмет переменную по ссылке и предоставит обеим функциям доступ к исходной переменной.

Кроме того, если getValue а также setValue реализовать некоторую форму блокировки, этот код не является потокобезопасным.

Проблема в том, что вы передаете pl1 по значению, когда вы хотите передать его по ссылке. Несмотря на то, что похоже, что вы передаете pl1 в каждую функцию, на самом деле происходит то, что потоки Move и Draw создают каждый новый объект Player. Если вы передадите по ссылкам, то оба потока будут ссылаться на один и тот же объект, а не создавать свои собственные копии. Попробуйте изменить подписи функций следующим образом:

static void Move(Player &p);
static void Draw(Player &p);

Кроме того, подумайте над тем, чтобы добавить в вашу функцию условие выхода. Поскольку while(1) никогда не завершится, функции join() будут ждать вечно. Надеюсь, это поможет!

Другие вопросы по тегам