假设我有一个类,在初始化后创建一个线程并在其中运行一个方法,在其中声明一个静态变量:
void method()
{
static int var = 0;
var++;
}
如果我创建了更多类的对象,例如3,那么该方法将在3个不同的线程中被调用3次。之后var
将等于3。
如何完成功能,其中每个线程都有自己的静态var
,独立于其他线程。我将非常感谢你的帮助。
答案 0 :(得分:33)
您可以使用thread_local
关键字指示对象具有线程存储持续时间。您可以这样使用它:
static thread_local int V;
如果您想了解有关存储类说明符的更多信息,可以查看CppReference。
答案 1 :(得分:13)
这是thread_local
存储类说明符的用途:
void method()
{
thread_local int var = 0;
var++;
}
这意味着每个线程都有自己的var
版本,它将在第一次运行该函数时初始化,并在线程退出时销毁。
答案 2 :(得分:7)
你在评论中说:
我确实想要一个特定于类
的每个实例的变量
这正是一个实例变量(例如,每个实例成员)。
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; } };
如果需要,可以通过在变量名称中包含方法名称来表明您的意图:
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;
}
答案 3 :(得分:-2)
好吧,如果你想要一个变量与线程不同,那么该变量不应该是静态的。它失去了一个静态变量的点,根据定义,它是一个变量:
你问的问题不是编码问题&#34;而是建筑问题。我不知道你正在开发什么样的系统/应用程序,也许你需要以不同的方式处理你的问题。
问自己这个问题:
如果你更具体,也许我可以给你一个更具体的答案/方法。