删除矢量内指针的适当方法

Appropriate way to delete pointers within a vector

本文关键字:方法 指针 删除      更新时间:2023-10-16

我有一个多线程聊天服务器,主服务器类有一个客户端的 std::vector。每个客户端都在自己的线程上运行,它们持有指向客户端向量的指针,以便它们可以相互通信。

我不确定的是,当客户端断开连接时,从此向量中删除对象的最佳方法是什么?

在这种情况下,是否可以只使用互斥锁锁定资源,然后允许它从客户端向量中删除/删除自身?

或者,拥有客户端向量的服务器对象最好执行某种检查以查看该连接是否已关闭,然后让该类管理资源的释放?

我对智能指针解决方案不感兴趣,这是一个学习项目。

遵循关注点分离的原则,从设计的角度来看,如果服务器在线程中启动客户端,我建议在服务器类中管理所有这些东西。

如果连接丢失,客户端线程可以通知服务器线程,然后服务器对象可以执行必要的操作以将客户端从其监视列表中删除并删除它。

一般的想法是这样的:

class Server; 
class Client {
    Server* myserver;    // edit: sorry I forgot the backreference 
    clientid_t id;       // unique id, provided by the server at construction
public: 
    clientid_t get_id(); // for server when searching for a specific client
    ...                 // when connection is lost, tell the server
    ...                 // the destructor will do everything needed to clean up/close a chat
};
class Server {
    vector<Client*> chats;   // Or better, a smart pointer
    mutex critical;   // used when accessing to the chats container. 
public:  
    void listen_for_new_chats();  // create new chats and insert them in container
    void close_chat (clientid_t id);  // called when chat lost connection (abort)    
                                      // this function shall remove the chat from container and destroy client 
    ...  
};

这使您可以完全控制服务器独立于客户端发展:

  • 如果有一天你选择队列或列表而不是Vector,客户将不需要知道。
  • 客户端不需要知道服务器如何管理客户端(直接分配、智能指针或直接作为容器中的对象(。

从并发的角度来看,这种封装也将使其更加可靠。 不仅在删除客户端时应锁定矢量,还应在访问它以进行读取/搜索时锁定矢量。 通过将向量保留为服务器的私有,可以确保永远不会通过放弃锁而无意中使用向量。