首先,我是一个学生,所以代码可能不是一个有效的或写得很好的。抱歉但如果你不介意的话我需要你的帮助。
下面是我的主程序和我在主程序中使用的musical_chairs函数。
void musical_chairs(IntQueueHW6 &my_queue, unsigned int idx,unsigned int remaining_player_num, vector<int> &players)
{
this_thread::sleep_until(chrono::system_clock::now() + chrono::seconds(2));
mtx.lock();
if(!(my_queue.isFull()))
{
my_queue.enqueue(idx);// my_queue is a queue with size of total_player_num-1
cout << "Player " << idx << " captured a chair at ";
current_time();
cout << "." << endl;
}
else
//**************** I believe this block causing the error *******************
not_capture(idx);
for(int k = 0; k < remaining_player_num; k++)
{
if(players[k] == idx)
{
players.erase(players.begin()+k);
break;
}
}
}
mtx.unlock();
//*************** I believe this block causing the error **********************
}
int main()
{
unsigned int total_player_num, total_round_num, remaining_player_num;
cout << "Welcome to Musical Chairs game!" << endl << "Enter the number of players in the game: " << endl;
cin >> total_player_num;
remaining_player_num = total_player_num;
total_round_num = total_player_num - 1;
cout << "Game Start!" << endl << endl;
vector<int> players(total_player_num); // creating a vector consists of players IDs
for(int i=0; i < total_player_num; i++)
{
players[i] = i;
}
while(remaining_player_num != 1) // until only one player left in te game
{
IntQueueHW6 my_queue(total_round_num); // creating a queue with size total_round_num for chair slots
vector<thread> threads(total_player_num); // create a thread vector for all players
cout << "Time is now ";
current_time();
cout << endl;
int players_length = players.size();
for(int i = 0; i < players_length; i++)
{
int idx = players[i];
threads[idx] = thread(&musical_chairs, ref(my_queue), idx, remaining_player_num, ref(players));
}
for(int i = 0; i < players_length; i++) //joining to threads
{
int idx = players[i];
if(threads[idx].joinable())
{
threads[idx].join();
}
}
display_remaining_players(players); // changing variables accordingly
remaining_player_num --;
total_round_num -- ;
my_queue.clear();
}
unsigned int winner_id = players[0];
winner_func(winner_id); // this function displays the winner
return 0;
}
我用多线程写了一个模拟“抢椅子”游戏的程序。当我运行主程序时,我得到“没有活动异常就终止调用”错误。由于我在互联网上的研究很少,这可能是因为线程超出范围,但如果是这样,我不知道如何修复它。谁能解释一下怎么解决?如果错误发生在不同的事情,你能解释一下吗?你能帮助我修复这个代码吗?先谢谢你了。
1条答案
按热度按时间4si2a6ki1#
调用
std::terminate
是因为一个线程没有被联接就终止了。musical_chairs
函数中的失败线程将自己从播放器向量中删除,但与此同时,main
线程继续执行,循环调用join
的线程。这里缺少同步将导致随机失败,具体取决于线程调度的变化。考虑到代码结构,这将需要重新考虑才能修复。下面是我能想到的最简单的实现。它使用
std::atomic
而不是std::mutex
,这样效率更高。几个快速注解:
std::set
而不是std::vector
,因为玩家ID是唯一的,并且从集合中删除元素比向量更容易和更有效。middle
线程作为每一轮的失败者--否则,最后一个线程会经常失败。pid
必须通过值捕获,这样每个线程都有自己的播放器id,但是queue
、chairs
和loser
需要通过引用捕获,因为它们都是跨线程共享的。示例代码
输出