【发布时间】:2021-01-31 07:59:59
【问题描述】:
我有一个具有踢球功能的玩家类,我需要稍等片刻,然后由于我无法控制的原因踢出玩家,而且我还需要在等待时不持有该功能,所以我的问题是; 当线程完成等待并踢玩家时,断开连接事件被触发并且玩家的内存被立即释放,这导致明显未完成的线程在那一刻持续导致崩溃。
class Player
{
public:
Player();
void kick();
void kick(const char*, int color);
protected:
std::thread delaydKick_;
private:
};
void Player::kick(){
sampgdk_Kick(playerid); //tells API to kick the player
}
void Player::kick(const char* m, int color){
sendMessage(m, color); // sends message to the player using API
delaydKick_ = std::thread([p = this](){
std::this_thread::sleep_for(std::chrono::seconds(3));
p->kick(); //calls the function from the player object defined above
});
sampgdk::logprintf("Kicked (%s); %s", playername, m); //sends log to the server using API
}
//gets called by API when player disconnects
//PlayerDisconnectEvent just contains a pointer to the player which is on the heap
bool VirtualServerManager::OnPlayerDisconnect(PlayerDisconnectEvent&& e){
//if disconnect is not kick
if(e.player != nullptr){
if( ( e.reason < 2 ) && ( e.player->loggedIn == true ) ){
e.player->getRefresh();
e.player->updatePlayTime();
SQLHandler sqlh(&sqlc);
PlayerPersistance::save(e.player, &sqlh);
}
players.del(e.player->playerid); //here the player gets deleted when the api rises the event
}
return true;
}
函数del的定义:
template <typename T>
void List<T>::del(size_t index){
if(index >= current_max_){
throw "pointer out of range";
}
if(items_[index] != nullptr){
delete items_[index]; // it just calls delete on the pointer which is on the heap
items_[index] = nullptr;
count_--;
}
}
需要澄清的是,包含线程对象的播放器堆上的内存被删除,因此终止线程对象 (delaydKick_) 会导致以下崩溃:
在没有活动异常的情况下终止调用
尝试在玩家的析构函数中加入线程会导致:
在抛出 'std::system_error' 的实例后调用终止 what():避免资源死锁
在创建线程后分离线程可以解决问题,但我想知道为什么会发生这些错误,尤其是当我在 Player 类析构函数上加入线程时。 另外我想知道是否有一种方法可以在不将线程与播放器分离的情况下解决这个问题。
【问题讨论】:
-
您的问题中有很多内容,但并非所有内容都像需要的那样清楚。什么断开连接事件?什么内存被释放?崩溃发生在哪里?加入什么析构函数?这一切都不是显而易见的。请尝试提出minimal reproducible example。
-
这样更好吗?
-
不,您的代码仍然依赖于未定义的“VirtualServerManager”之类的东西。尝试组合一个新的minimal reproducible example,它实际上可以按原样编译并演示您所询问的问题。
-
已经得到了两个非常好的答案,无论如何感谢您的宝贵时间:3。
标签: c++ multithreading