Talk about thread-local storage in Linux (1)--What is TLS

Source: Internet
Author: User

Starting with this article is another topic: Thread local Storage (threads locally Storage), before you introduce this concept, talk about variables and multithreading related knowledge.

Variable model under multi-threading

In a single-threaded model, a variable is defined with two dimensions, that is, where it is defined, and its modified properties (static, Extern,auto,register, and so on). The Extern property indicates that a variable is declared, independent of the definition, and not discussed here, while the register optimizes the variables into registers without discussion. The modifier properties associated with the variable definition are only auto and static. These two dimensions give you the types of variables and their behavior. Evaluate the behavior of a variable by often being from visibility and
The life cycle is assessed in terms of "where to define" and "Modify attributes" for variables, to derive "variable type" and to list a complete table from "visibility" and "life cycle" as follows:

where to define Modifier Properties Variable Type Life cycle Visibility of
Outside the function Auto Global variables The entire program Globally visible
Outside the function Static Global static variables The entire program The same. c file is visible
Within a function Auto Local variables function begins execution to the end of the period Visible within function
Within a function Static Static local Variables The entire program Visible within function

There is a question about static local variables, which can only be used within a function, why is its life cycle global? In fact, it is not the same as the local variable, the local variable is created when the function begins execution, at the end of the function execution, it disappears, does not exist. While a static local variable, when the function is not executed, it already exists, which is why it is the whole life cycle of the program . When the function execution is finished, it still exists, and the next time the function is executed, it is executed based on the result of the previous execution. So it behaves the same as a global variable, except that it can be accessed only within a function.

Under single-threaded programming, all of this is well coordinated. Because the entire process has only one execution unit, there is only one execution code (or function) that accesses the same variable at any given time.

In multithreaded mode, however, all of this has changed. Under multithreaded mode, multiple execution units occur at the same time, i.e. the same function runs in multiple execution units at the same time

It is not necessary to bring up multiple threads and almost all remember to protect data by applying locks.

The local variables (life cycle in the function) are not affected by multithreading, because each line stacks is independent, multiple threads execute the function concurrently, and the variable part of the access board is one copy of each thread, and does not produce data contention (race).

But it's not that much of a global variable, a global static variable, or a static local variable that has a life cycle as an entire program . Data contention occurs when multiple execution units are accessing the variable at the same time under multi-threading. In this case, it is necessary to use lock for data protection in order to guarantee the correctness of the program logic.

Locking, the intuitive response is to put part of the code back to the era of serial execution, if the locking is very frequent, the whole process can execute concurrently the code is not high, the use of multi-threaded acceleration ratio is not high, the most important is not based on the number of processors to dynamically scale.

In the multi-route programming, many times the data is divided, different data regions to different threading, you can avoid multi-threading in the competition to access data. One problem to consider, however, is if individual threads execute functions (usually different threads execute the same function, but they do not have access to the same data), can the intermediate output of these functions be thread independent ? If you can be completely independent, there is no need for mutual exclusion between multiple threads and optimal scalability.

There are two solutions to this problem, with the first thought being that the inputs and outputs of these functions are all passed with parameters. But it is very demanding for programming, and sometimes such designs are often not optimal. Many times the intermediate output of the function needs to be saved using global variables (of course we don't recommend global variables flying around, but static global variables are common in a module), which requires lock protection and inefficiency.

In this scenario, each thread wants to see the global variables themselves, it does not want to see others, do not want others to modify it, it does not want to modify others, the global variable is also a form, the ultimate goal is that it can have a separate copy .

In order to solve the problem of high-efficiency programming under multi-threading, we must modify the original variable model slightly, and support an additional attribute, that is, whether the variable is a multiple execution unit (thread) sharing or a separate copy.

exclusive
where to define Modifier Properties multiple execution unit sharing orVariable Type Life cycle Visibility of
Outside the function Auto Shares Global variables The entire program Globally visible
Outside the function Auto Exclusive Global Thread variables The entire program Globally visible
Outside the function Static Shares Global static variables The entire program The same. c file is visible
Outside the function Static Exclusive Global static thread variables The entire program The same. c file is visible
Within a function Auto Exclusive Local variables Only when the function begins execution to the end of the period Within a function
Within a function Static Shares Static local Variables The entire program Visible within function
Within a function Static Exclusive Static local thread variables The entire program Visible within function

Note that the local variable is inherently exclusive to the thread function, so it does not share this property value, and the variables for the entire program life cycle share and enjoy these two property values.

What is TLS

Write here, the definition of TLS is self-evident. TLS is all called the thread local Storage, that is, threads are stored locally. In single-threaded mode, all variables in the entire program life cycle are only one, because it is just an execution unit, while in multithreaded mode, some variables need to support each thread's ability to enjoy one share. This per-thread-exclusive variable is placed in a dedicated storage area for each thread, so it is called thread local storage (thread locally Storage) or thread-private data (threaded specific).

Linux supports two ways of defining and using TLS variables, as shown in the following table:

How to define Support Hierarchy access Mode
__thread keywords Language level Exactly the same as the global variable
Pthread_key_create function Run-level Library Pthread_get_specific and pthread_set_specific to read and write thread variables

The __thread keyword supported by the application language is the simplest, and only needs to add a __thread keyword when defining the variable, and subsequent access to the variable remains completely intact, so this is supported at the language level and is implicit. The _thread keyword is a gcc extension of the C language, not defined by the C language standard, and of course the visual stdio under Windows expands with another keyword.

__thread Example

Here's a simple example of how the __thread keyword is used, and the actual effect.

__threadintvar =0;//var is defined as thread variable, and each number line has one copyvoid* Worker (void* arg);intMain () {pthread_t pid1,pid2; Pthread_create (&pid1,null,worker, (void*)0); Pthread_create (&pid2,null,worker, (void*)1);      Pthread_join (Pid1,null); Pthread_join (Pid2,null);return 0; }void* Worker (void* Arg) {intIDX = (int) Arg;intI for(i =0; I < -; ++i) {printf("thread:%d ++var =%d\n", IDX, ++var);//Each thread only accesses its own share}}

The thread variables created and used using the Pthread_key_create/pthread_get_specific/pthread_set_specific function are described later, and we will not discuss them for the time being.

Later in the article, we use the term thread variable to represent a variable that each thread has a single copy of, and a TLS statement is used to represent a generic representation of the properties stored in this class of variables.

Talk about thread-local storage in Linux (1)-What is TLS

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.