thread_local 非静态数据成员的数据,再一次
thread_local data for non static data members, once more
问题
c++11引入了thread_local
,它提供了线程本地数据,但不能与非静态数据成员一起使用。
由此引出问题:
答案:
... I suggest using boost::thread_specific_ptr
. You can put one of these inside your class and get the behavior you want.
但是boost::thread_specific_ptr
destructor has the following note附上:
All the thread specific instances associated to this thread_specific_ptr (except maybe the one associated to this thread) must be null.
有办法解决这个问题吗?
我需要非静态数据成员的线程本地存储,这将在销毁时释放所有线程数据,即使仍有线程 运行 (或至少在销毁时没有 fail/leak 的 tls ).
如果 boost::thread_specific_ptr
不是正确的选择,我可以使用互斥保护 std::vector
代替吗?
背景
我有一个 threadsafe class 从 mongodb.
接收数据
class JsonTable
{
public:
std::string getData() const;
//....
private:
ThreadLocalStorage<mongocxx::client> _clients;
//....
};
mongocxx::client
不得跨多个线程共享。
因此,为了使 getData
线程安全,我需要为每个线程构造一个 mongocxx::client
。当我的 JsonTable
class 被破坏时,我希望所有客户端都是 closed/destructed 即使最初创建它们的线程仍然是 运行.
创建一个从 ptr-to-this 到围绕 shared-ptr 到 shared-ptr 到数据的包装器的线程本地静态映射。
创建共享指针到共享指针到数据的非静态同步列表。
按需填充线程本地映射。填充后,将其添加到实例列表中。
在对象销毁时,使用原子共享 ptr 操作从列表的所有元素中清除内部 shared_ptr。这将删除线程局部实例数据。
双共享指针的包装器也使用原子操作来清除内部共享指针。如果线程死亡,这将清除数据。
实例和线程一起共享一个共享指针(内部),其生命周期由外部共享指针管理(因此当线程和实例都消失时它会死亡)。
唯一的同步发生在对象被销毁或新线程访问对象时,这应该能保持稳定的性能;
映射条目(带有空数据)比实例更持久。如果需要,您可以花一些时间以某种方式定期清理它们。如果您有许多瞬态实例与许多持久线程相互作用,则可能会出现问题。添加一个使用中数据与已清除数据的原子计数器,当它变高时,在添加新条目时通过删除已清除条目。
问题
c++11引入了thread_local
,它提供了线程本地数据,但不能与非静态数据成员一起使用。
由此引出问题:
答案:
... I suggest using
boost::thread_specific_ptr
. You can put one of these inside your class and get the behavior you want.
但是boost::thread_specific_ptr
destructor has the following note附上:
All the thread specific instances associated to this thread_specific_ptr (except maybe the one associated to this thread) must be null.
有办法解决这个问题吗?
我需要非静态数据成员的线程本地存储,这将在销毁时释放所有线程数据,即使仍有线程 运行 (或至少在销毁时没有 fail/leak 的 tls ).
如果 boost::thread_specific_ptr
不是正确的选择,我可以使用互斥保护 std::vector
代替吗?
背景
我有一个 threadsafe class 从 mongodb.
接收数据class JsonTable
{
public:
std::string getData() const;
//....
private:
ThreadLocalStorage<mongocxx::client> _clients;
//....
};
mongocxx::client
不得跨多个线程共享。
因此,为了使 getData
线程安全,我需要为每个线程构造一个 mongocxx::client
。当我的 JsonTable
class 被破坏时,我希望所有客户端都是 closed/destructed 即使最初创建它们的线程仍然是 运行.
创建一个从 ptr-to-this 到围绕 shared-ptr 到 shared-ptr 到数据的包装器的线程本地静态映射。
创建共享指针到共享指针到数据的非静态同步列表。
按需填充线程本地映射。填充后,将其添加到实例列表中。
在对象销毁时,使用原子共享 ptr 操作从列表的所有元素中清除内部 shared_ptr。这将删除线程局部实例数据。
双共享指针的包装器也使用原子操作来清除内部共享指针。如果线程死亡,这将清除数据。
实例和线程一起共享一个共享指针(内部),其生命周期由外部共享指针管理(因此当线程和实例都消失时它会死亡)。
唯一的同步发生在对象被销毁或新线程访问对象时,这应该能保持稳定的性能;
映射条目(带有空数据)比实例更持久。如果需要,您可以花一些时间以某种方式定期清理它们。如果您有许多瞬态实例与许多持久线程相互作用,则可能会出现问题。添加一个使用中数据与已清除数据的原子计数器,当它变高时,在添加新条目时通过删除已清除条目。