C++11 中的 thread_local 是什么意思?
我对 C++11 中 thread_local
的描述感到困惑.我的理解是,每个线程在函数中都有唯一的局部变量副本.所有线程都可以访问全局/静态变量(可能使用锁进行同步访问).thread_local
变量对所有线程都是可见的,但只能由为其定义的线程修改?这是正确的吗?
I am confused with the description of thread_local
in C++11. My understanding is, each thread has unique copy of local variables in a function. The global/static variables can be accessed by all the threads (possibly synchronized access using locks). And the thread_local
variables are visible to all the threads but can only modified by the thread for which they are defined? Is it correct?
推荐答案
线程局部存储持续时间是一个术语,用于指看似全局或静态的存储持续时间(从使用它的函数的角度来看)但在实际上,每个线程只有一个副本.
Thread-local storage duration is a term used to refer to data that is seemingly global or static storage duration (from the viewpoint of the functions using it) but in actual fact, there is one copy per thread.
它添加到当前自动(存在于块/函数期间)、静态(存在于程序持续时间)和动态(存在于分配和释放之间的堆上).
It adds to the current automatic (exists during a block/function), static (exists for the program duration) and dynamic (exists on the heap between allocation and deallocation).
线程本地的东西在线程创建时就存在,并在线程停止时处理.
Something that is thread-local is brought into existence at thread creation and disposed of when the thread stops.
下面是一些例子.
考虑一个随机数生成器,其中必须在每个线程的基础上维护种子.使用线程本地种子意味着每个线程都有自己的随机数序列,独立于其他线程.
Think of a random number generator where the seed must be maintained on a per-thread basis. Using a thread-local seed means that each thread gets its own random number sequence, independent of other threads.
如果你的种子是随机函数中的一个局部变量,它会在你每次调用它时被初始化,每次都给你相同的数字.如果是全局的,线程会干扰彼此的序列.
If your seed was a local variable within the random function, it would be initialised every time you called it, giving you the same number each time. If it was a global, threads would interfere with each other's sequences.
另一个示例类似于 strtok
,其中标记化状态存储在特定于线程的基础上.这样,单个线程可以确保其他线程不会破坏其标记化工作,同时仍然能够通过多次调用 strtok
来维护状态 - 这基本上呈现 strtok_r代码>(线程安全版本)是多余的.
Another example is something like strtok
where the tokenisation state is stored on a thread-specific basis. That way, a single thread can be sure that other threads won't screw up its tokenisation efforts, while still being able to maintain state over multiple calls to strtok
- this basically renders strtok_r
(the thread-safe version) redundant.
这两个例子都允许线程局部变量存在于使用它的函数中.在预线程代码中,它只是函数内的静态存储持续时间变量.对于线程,修改为线程本地存储持续时间.
Both these examples allow for the thread local variable to exist within the function that uses it. In pre-threaded code, it would simply be a static storage duration variable within the function. For threads, that's modified to thread local storage duration.
还有一个例子,比如errno
.您不希望在您的一次调用失败后但在检查变量之前修改 errno
的单独线程,但您只需要每个线程一个副本.
Yet another example would be something like errno
. You don't want separate threads modifying errno
after one of your calls fails but before you can check the variable, and yet you only want one copy per thread.
本网站对不同的存储期限说明符进行了合理的描述.
This site has a reasonable description of the different storage duration specifiers.
相关文章