我正在制作一个用户与电脑对战的游戏。计算机对手考虑下一步行动,而它是玩家的回合。如果玩家移动到计算机对手计划移动的位置,则计算机对手开始搜索其移动的位置。
这里是主要功能和对手功能的概述:
[增订]
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);
}
}
目前,似乎正是这样:[更新]
然后,没有任何反应。
我想要发生什么(将互斥锁锁定在适当的位置):
我对线程并不是很有经验,所以有人可以帮助我解决这里发生的事情,以及我如何解决这个问题?我不知道我是否在正确的位置有互斥锁定/解锁,条件信号/等待和setCurrentPlayer功能。
答案 0 :(得分:2)
当您调用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
}
和其他线程类似。
答案 1 :(得分:1)
在等待之前你应该锁定 等待并在等待信号后将其解锁,如下所示:
//...
while(!isGameOver()) {
pthread_mutex_lock(&mutex);
if(getCurrentPlayer() != PLAYER) {
pthread_cond_wait(&cond, &mutex);
}
pthread_mutex_unlock(&mutex);
// ...
另见:https://computing.llnl.gov/tutorials/pthreads/
他们在那里有很容易理解的例子。
答案 2 :(得分:1)
另一个注意事项:在调用pthread_create();
之前,您应该运行这两行
无法保证在这两行之前执行您的线程。
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&cond, NULL);