如何在多线程程序中安全地销毁共享对象

How can I destroy a shared object safely in a multi-threaded program?

本文关键字:共享 对象 安全 多线程 程序      更新时间:2023-10-16

我设计了一些类。是这样的:

  1. ClientEntity可以有多个实例。
  2. 创建ClientEntity对象时,它不会被修改,所以我不使用互斥锁。
  3. 可以在不同线程之间访问ClientEntity对象。
  4. ClientEntity对象在收到一些退出命令时将被销毁。
  5. 某些线程可以访问ClientEntity对象。

如何安全地销毁此对象?

class ClientEntity
{
public:
    conference_info & conf_info (){return conf_info_;}
    void conf_info(const conference_info &ci){conf_info_ = ci;}
    user_info & usr_info(){return usr_info_;}
    void usr_info(const user_info &ui){usr_info_ = ui;}
private:
    web_conf_info *wci_;
    user_info usr_info_;
    conference_info conf_info_;
    // .....
};
class user_info
{
public:
    user_info & operator = (const user_info &ui)
    {   
        if (this != &ui){
            user_id = ui.user_id;
            user_name = ui.user_name;
            user_role = ui.user_role;
        }   
        return *this;
    }   
public:
    int user_id;
    int user_role;
    std::string user_name;
};

class conference_info
{
public:
    conference_info & operator = (const conference_info &conf)
    {   
        if (this != &conf){
            conf_id = conf.conf_id;
            dtsip_list = conf.dtsip_list;
            ctsip_list = conf.ctsip_list;
        }   
        return *this;
    }
public:
    int conf_id;
    std::list<std::string> dtsip_list;
    std::list<std::string> ctsip_list;
};

确定可以(或不能)删除共享对象的典型方法是使用引用计数 - 通过使用"共享指针",或者作为类本身中您自己的逻辑的一部分。您必须具有客户端代码使用的某种函数来表示"我想使用此对象",从而增加引用计数。客户端完成后,它会调用"我不再对此对象感兴趣",并倒计时引用计数。如果引用计数变为零(并且由于其他原因不需要该对象),则可以将其删除。

我建议在创建ClientEntity对象时,您应该确保它由另一个对象(例如全局对象)正确拥有,当全局对象被销毁时,删除ClientEntity

当然,您可以在多个线程之间随时删除ClientEntity,但是当您尝试删除ClientEntity时,请使用像关键部分这样的同步对象。

访问ClientEntity的其他线程也应该使用关键部分等,以防止对象在使用时被删除。

我使用了自己的类来执行引用计数。 我做了一个搜索,发现可以使用:

使用shared_ptr的示例?

http://www.boost.org/doc/libs/1_52_0/libs/smart_ptr/shared_ptr.htm