每个线程的局部静态变量
Local static variables for each thread
假设我有一个类,在初始化后创建了一个线程并在其中运行了一个方法,在它内部声明了一个静态变量:
void method()
{
static int var = 0;
var++;
}
如果我创建了更多的类对象,例如3,那么该方法将在3个不同的线程中被调用3次。之后,var
等于3。如何实现该功能,其中每个线程都有自己独立于其他线程的静态var
。
您可以使用thread_local
关键字,表示该对象具有线程存储持续时间。你可以这样使用:
static thread_local int V;
如果您想了解更多关于存储类说明符的信息,可以查看CppReference
这就是thread_local
存储类说明符的作用:
void method()
{
thread_local int var = 0;
var++;
}
这意味着每个线程都有自己版本的var
,在第一次运行该函数时初始化,在线程退出时销毁。
你在评论中说:
我确实想要一个特定于类的每个实例的变量
这就是实例变量(也就是每个实例的成员)。
static
成员和函数局部变量不是特定于类的每个实例的 !它们要么是完全全局的(每个可执行文件一个实例),要么是每个线程,如果你使用c++ 11并将它们声明为thread_local
。
绝对需要一个成员变量。这是保证变量对于类的每个实例都是特定的唯一方法。
您可能认为应该为类的每个实例创建一个专用线程。首先,很可能你不应该这么做。其次,如果您改变主意,停止创建每个类的线程,而使用线程池,那么您的代码将立即中断。
因此,正确和直接的事情是将其作为实例变量(而不是类变量):// OK - instance variable
class C { int var; };
// WRONG - class variable and lookalikes
class C { static int var; };
class C { void foo() { static int var; } };
// WRONG - thread variable, but **not** instance variable
class C { static thread_local int var; };
class C { void foo() { static thread_local int var; } };
如果你愿意,你可以通过在变量name中包含方法名来表明你的意图:
class C {
int foo_var;
C() : foo_var(0) {}
void foo() { ... }
};
最后,如果您可以接受更多的类型,您可以使用成员包装器来强制它所使用的范围:
#include <utility>
#include <cassert>
template <typename T, typename Member, Member member>
class ScopedMember {
T data;
public:
explicit ScopedMember(const T & d) : data(d) {}
explicit ScopedMember(T && d) : data(std::move(d)) {}
ScopedMember() {}
template <Member m, void(*)(char[member == m ? 1 : -1]) = (void(*)(char[1]))0>
T & use() { return data; }
template <Member m, void(*)(char[member == m ? 1 : -1]) = (void(*)(char[1]))0>
const T & use() const { return data; }
};
class C {
public:
C() : m_foo(-1) {}
void granted() {
auto & foo = m_foo.use<&C::granted>();
foo = 5;
assert(m_foo.use<&C::granted>() == 5);
}
void rejected() {
#if 0
// Won't compile
auto & foo = m_foo.use<&C::rejected>();
#endif
}
private:
ScopedMember<int, void(C::*)(), &C::granted> m_foo;
};
int main()
{
C().granted();
return 0;
}
如果你想让一个变量在不同的线程之间不同,那么这个变量不应该是静态的。它失去了静态变量的意义,根据定义,静态变量是:
- 由该类的所有对象共享。
- 不需要类实例(对象)来访问。
你问的问题不是一个"编码问题",而是一个架构问题。我不知道你在开发什么样的系统/应用,也许你需要用不同的方法来解决你的问题。
问自己这些问题:
- 为什么我需要线程?
- 为什么我需要这个变量是静态的?
- 我需要在线程之间共享哪些信息,不想共享哪些信息?
如果你更具体,也许我可以给你一个更具体的答案/方法。
- 在 .h 文件中的类中声明静态变量和在.cpp文件中声明"global"变量有什么区别
- 模板基类中的静态变量
- 类和静态变量
- 不同作用域中的静态变量和全局变量
- 静态变量声明和定义
- 是否可以依赖函数范围的静态变量来执行程序关闭期间调用的方法?
- 在类中继承静态变量?
- "local scope"中的 C++ 初始化静态变量
- 使用静态变量的递归调用的不同输出
- 复制文件流C++静态变量
- 跨模板化函数编译的静态变量
- C++编译器是否优化了顺序静态变量读取?
- C++,每个循环初始化一个新的静态变量
- (为什么)我们可以在初始化中将非静态类成员分配给静态变量吗?
- 这些语句是否等效(静态变量、常量变量和泛型)
- 程序如何知道静态变量是否需要初始化?
- 类外的静态变量实例化
- 无法解析静态变量
- 函数局部静态变量:从性能角度来看的优点/缺点
- 访问从 CPP 文件到其他头文件的静态变量