我正在制作一个用户在计算机上玩的游戏。轮到玩家时,计算机对手考虑下一步行动。如果玩家移动到计算机对手计划移动的位置,则计算机对手将再次开始搜索其移动。

以下是主要功能和对手功能的概述:

[更新]

pthread_mutex_t mutex;
pthread_cond_t cond;

int main() {
    // ... initialize game variables, args to pass to opponent ...

    pthread_t thread;
    pthread_create(&thread, NULL, opponent, &args);
    pthread_mutex_init(&mutex, NULL);
    pthread_cond_init(&cond, NULL);

    while(!isGameOver()) {
        pthread_mutex_lock(&mutex);

        if(getCurrentPlayer() != PLAYER) {
            pthread_cond_wait(&cond, &mutex);
        }

        if(getCurrentPlayer() == PLAYER) {
            // ... update board with player's move ...

            setCurrentPlayer(OPPONENT);

            pthread_cond_signal(&cond);
        }

        pthread_mutex_unlock(&mutex);
    }
}

void * opponent(void * args) {
    // initialize move to something invalid

    while(!isGameOver()) {
        if(!isValid(move)) {
            move = findMove();
        }

        pthread_mutex_lock(&mutex);

        if(getCurrentPlayer() != OPPONENT) {
            pthread_cond_wait(&cond, &mutex);
        }

        if(getCurrentPlayer() == OPPONENT) {
            if(isValid(move)) {
                // ... update board with opponent's move ...

                setCurrentPlayer(PLAYER);

                pthread_cond_signal(&cond);
            }
        }

        pthread_mutex_unlock(&mutex);
    }
}

目前看来,这是正在发生的事情:[更新]

对手找到自己的棋子(findMove)
  • 对手锁定互斥锁(pthread_mutex_lock)
  • 对手开始等待
  • (pthread_cond_wait)
  • 主要功能锁定互斥锁(pthread_mutex_lock)
  • 玩家移动了自己的棋子。
  • 主线程发出信号,表明对手已转(pthread_cond_signal)

  • 然后,什么也没有发生。

    我想发生的事情(互斥锁被锁定在适当的位置):

    对手找到自己的棋子(findMove) 对手开始等待
  • (pthread_cond_wait)
  • 玩家移动了自己的棋子。
  • 主线程发出信号,表明对手已转(pthread_cond_signal)
  • 对手停止等待
  • 对手做出了之前考虑
  • 的 Action
  • 对手切换当前播放器(setCurrentPlayer)
  • 重复

  • 我对线程没有真正的经验,因此有人可以帮助我解决这里发生的事情以及如何解决它吗?我不知道是否在正确的位置具有互斥锁锁定/解锁,条件信号/等待和setCurrentPlayer函数。

    最佳答案

    调用pthread_cond_wait时,互斥锁应该被锁定-该函数自动解锁互斥锁,等待信号,然后在返回之前重新锁定该互斥锁。互斥锁的目的是将对共享状态(在此情况下为当前播放器)的访问序列化,因此应将其锁定在对该状态的任何访问周围。循环应该更像:

    while(!isGameOver()) {
        if(!isValid(move)) {
            move = findMove();
        }
    
        pthread_mutex_lock(&mutex);  // LOCK HERE
        if(getCurrentPlayer() != OPPONENT) {
            pthread_cond_wait(&cond, &mutex);
        }
    
        if(getCurrentPlayer() == OPPONENT) {
            if(isValid(move)) {
                // NOT HERE pthread_mutex_lock(&mutex);
    
                // ... update board with opponent's move ...
    
                setCurrentPlayer(PLAYER);
    
                pthread_cond_signal(&cond);
                // NOT HERE pthread_mutex_unlock(&mutex);
            }
        }
        pthread_mutex_unlock(&mutex); // UNLOCK HERE
    }
    

    和其他线程类似。

    10-08 11:29