当前位置:  开发笔记 > 编程语言 > 正文

如何为每个实例提供非静态线程局部变量

如何解决《如何为每个实例提供非静态线程局部变量》经验,为你挑选了1个好方法。

问题本身:

class B{/*...*/};
class A {
    /* members */
    NON-static thread_local B var; // and a thread_local variable here
    ret_t method(/* args */);
};

我想var独立存在每个线程和每个实例.

更大(完整)的问题:

实例A跨线程共享.B是调用所需的一些资源A::method,它必须是独立的线程才能避免竞争条件(即A::method必须具有"写访问权限" var).B对于不同的实例,相应的是不同的A.

我提出的一个不完全令人满意的方法是让一些容器(比如说std::unordered_map)存储每个var对应于每个thread实例的容器.但是,这既不限制var跨线程访问s也不会阻止整个容器被修改.(因此,要求开发人员要小心,以便编写安全的代码.)


我在SO上看过一些关于java ThreadLocal关键字(?)的帖子,但它们似乎都没有提供真正有用的想法.有什么建议吗?



1> Martin Bonne..:

您不能声明非静态成员thread_local.见cppreference.特别是:

thread_local关键字仅允许在命名空间范围内声明的对象,在块范围内声明的对象和静态数据成员.

如果你不想使用pthreads(在Windows上很棘手),一些容器是你唯一的选择.

一种选择是变体std::unordered_map.(您可以编写一个类来包装它并使用互斥锁保护地图.)

另一种最初有吸引力的选择是一个thread_local静态成员的A它映射A*B将避免任何需要锁.

class A {
    static thread_local std::unordered_map s_B;
    ....
};

用法:

void A::foo() {
    B& b = s_B[this];  // B needs to be default constructable.
    ...

问题是你需要一些方法来从s_B地图中删除元素.如果A对象实际上被锁定到特定线程,或者如果你有某种方法可以在另一个线程上调用函数,那么这不是太大的问题- 但它也不是完全无关紧要的.(您可能会发现使用一个A增量64位计数器的唯一标识符更安全- 这样,在销毁A对象和消息之间重复使用标识符的风险要小得多,以便B从正在处理的所有地图中删除它. )

推荐阅读
LEEstarmmmmm
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有