简体   繁体   English

每个线程的局部静态变量

[英]Local static variables for each thread

Lets say I have a class that after initialization creates a thread and runs a method in it, within it declares a static variable: 假设我有一个类,在初始化之后创建一个线程并在其中运行一个方法,在其中声明一个静态变量:

void method()
{
     static int var = 0;
     var++;
}

If I create more objects of the class, for example 3, then the method will be called 3 times in 3 different threads. 如果我创建了更多类的对象,例如3,那么该方法将在3个不同的线程中被调用3次。 After that var will equal 3. How to accomplish the functionality, where each thread has its own static var that is independent of others. 之后var将等于3.如何完成功能,其中每个线程都有自己的静态var ,独立于其他线程。 I would appreciate all help. 我将非常感谢所有的帮助。

You can use the thread_local keyword which indicates that the object has a thread storage duration. 您可以使用thread_local关键字指示对象具有线程存储持续时间。 You can use it like that : 你可以像这样使用它:

static thread_local int V;

If you want more information about storage class specifiers, you can check CppReference . 如果需要有关存储类说明符的更多信息,可以查看CppReference

This is what the thread_local storage class specifier is for: 这就是thread_local存储类说明符的用途:

void method()
{
     thread_local int var = 0;
     var++;
}

This means that each thread will have its own version of var which will be initialized on the first run through that function and destroyed on thread exit. 这意味着每个线程都有自己的var版本,它将在第一次运行该函数时初始化,并在线程退出时销毁。

You said, in a comment: 你在评论中说:

I do want a variable that is specific for each instance of a class 我确实想要一个特定于每个类实例的变量

That's precisely what an instance variable is (aka a per-instance member). 这正是实例变量(也就是每个实例成员)。

static members and function local variables are not specific to each instance of a class! static成员和函数局部变量不是特定于每个类的实例! They are either completely global (one instance per entire executable), or are per-thread if you use C++11 and declare them thread_local . 它们要么是完全全局的(每个可执行文件一个实例),要么是每个线程,如果你使用C ++ 11并将它们声明为thread_local

You absolutely need a member variable. 你绝对需要一个成员变量。 That's the only way to guarantee that the variable will be specific for each instance of the class. 这是保证变量将特定于每个类实例的唯一方法。

You might argue that you create a dedicated thread per each instance of the class. 您可能会争辩说,您为每个类的实例创建一个专用线程。 First of all, it's likely that you shouldn't be doing that. 首先,你可能不应该这样做。 Secondly, if you ever change your mind, and stop creating a per-class thread and, say, use a thread pool instead, your code will instantly break. 其次,如果你改变主意,并停止创建每个类的线程,比如使用线程池,你的代码将立即中断。

So, the proper and straightforward thing is to have it as an instance variable (as opposed to a class variable): 因此,正确和直接的事情是将它作为实例变量(而不是类变量):

// 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; } };

If you want, you can indicate your intent by including the method's name in the variable name: 如果需要,可以通过在变量名称中包含方法名称来表明您的意图:

class C {
  int foo_var;
  C() : foo_var(0) {}
  void foo() { ... }
};

Finally, if you're OK with a bit more typing, you can use a member wrapper to enforce the scope it's used in: 最后,如果你可以输入更多内容,可以使用成员包装器来强制执行它所使用的范围:

#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;
}

Well, if you want a variable to be different from thread to thread, that variable should not be static. 好吧,如果你想要一个变量与线程不同,那么该变量不应该是静态的。 It's looses the point of a static variable, which is, by definition, a variable that: 它失去了一个静态变量的点,根据定义,它是一个变量:

  1. It's shared by all objects of that class. 它由该类的所有对象共享。
  2. It does not need an class instance (object) to be accessed. 它不需要访问类实例(对象)。

The question you're asking it's not a "coding problem", but an architectural one. 你问的问题不是“编码问题”,而是建筑问题。 I don't know what kind of system/app you're developing, maybe you need to approach your problem in a different way. 我不知道你正在开发什么样的系统/应用程序,也许你需要以不同的方式处理你的问题。

Ask yourself this questions: 问自己这个问题:

  • Why do I need threads? 为什么我需要线程?
  • Why do I need this variable to be static? 为什么我需要这个变量是静态的?
  • What information do I need to share between threads and what information I don't want to share? 我需要在线程之间共享哪些信息以及我不想分享哪些信息?

If you are more specific, maybe I can give you a more specific answer/approach. 如果你更具体,也许我可以给你一个更具体的答案/方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM