ArticleslgStudy

computer science

Thread-local storage

Thread-local storage is a computer science topic covered in the lgStudy science library. This page brings together a partial reference excerpt, illustrations, worked examples, real-world applications and a short study plan, so you can understand Thread-local storage rather than just read about it. In short: In computer programming, thread-local storage (TLS) is a memory management method that uses static or global memory local to a thread. The concept allows storage of data that appears to be global in a system with separate threads.

Key takeaways

  • Thread-local storage belongs to computer science; place it in that map before memorising details.
  • Learn the definition first, then one example that makes the definition concrete.
  • Connect Thread-local storage to a quantity you can measure, compute or draw — that is where exam questions come from.
  • Reproduce the core statement of Thread-local storage from memory before moving on to harder problems.

Reference excerpt

In computer programming, thread-local storage (TLS) is a memory management method that uses static or global memory local to a thread. The concept allows storage of data that appears to be global in a system with separate threads. Many systems impose restrictions on the size of the thread-local memory block, in fact often rather tight limits. On the other hand, if a system can provide at least a memory address (pointer) sized variable thread-local, then this allows the use of arbitrarily sized memory blocks in a thread-local manner, by allocating such a memory block dynamically and storing the memory address of that block in the thread-local variable. On RISC machines, the calling convention often reserves a thread pointer register for this use.

Usage While the use of global variables is generally discouraged in modern programming, some older operating systems such as UNIX were originally designed for uniprocessor hardware and often use global variables to store important values. An example is the errno used by many functions of the C library. On a modern machine, where multiple threads may be modifying the errno variable, a call of a system function on one thread may overwrite the value previously set by a call of a system function on a different thread, possibly before following code on that different thread could check for the error condition. The solution is to have errno be a variable that looks as if it is global, but is physically stored in a per-thread memory pool, the thread-local storage. A second use case would be multiple threads accumulating information into a global variable. To avoid a race condition, every access to this global variable would have to be protected by a mutex. Instead, each thread might accumulate into a thread-local variable, thereby eliminating any possibility of a race condition, thereby removing the need for locking. The threads then only have to synchronise a final accumulation from their own thread-local variable into a single global variable.

Windows implementation The application programming interface (API) function TlsAlloc can be used to obtain an unused TLS slot index; the TLS slot index will then be considered 'used'. The TlsGetValue and TlsSetValue functions are then used to read and write a memory address to a thread-local variable identified by the TLS slot index. TlsSetValue only affects the variable for the current thread. The TlsFree function can be called to release the TLS slot index. There is a Win32 Thread Information Block for each thread. One of the entries in this block is the thread-local storage table for that thread. Each call of TlsAlloc returns a unique index into this table. Each thread can independently use TlsSetValue(index, value) and obtain the specified value via TlsGetValue(index), because these set and look up an entry in the thread's own table. Apart from TlsXxx function family, Windows executables can define a section which is mapped to a different page for each thread of the executing process. Unlike TlsXxx values, these pages can contain arbitrary and valid addresses. These addresses, however, are different for each executing thread and therefore should not be passed to asynchronous functions (which may execute in a different thread) or otherwise passed to code which assume that a virtual address is unique within the whole process. TLS sections are managed using memory paging and its size is quantized to a page size (4kB on x86 machines). Such sections may only be defined inside a main executable of a program - DLLs should not contain such sections, because they are not correctly initialized when loading with LoadLibrary.

Pthreads implementation In the Pthreads API, memory local to a thread is designated with the term Thread-specific data. The functions pthread_key_create and pthread_key_delete are used respectively to create and delete a key for thread-specific data. The type of the key is explicitly left opaque and is referred to as pthread_key_t. This key can be seen by all threads. In each thread, the key can be associated with thread-specific data via pthread_setspecific. The data can later be retrieved using pthread_getspecific. In addition pthread_key_create can optionally accept a destructor function that will automatically be called at thread exit, if the thread-specific data is not NULL. The destructor receives the value associated with the key as parameter so it can perform cleanup actions (close connections, free memory, etc.). Even when a destructor is specified, the program must still call pthread_key_delete to free the thread-specific data at process level (the destructor only frees the data local to the thread).

Language-specific implementation Apart from relying on programmers to call the appropriate API functions, it is also possible to extend the programming language to support thread local storage (TLS).

C and C++ In C11, the keyword _Thread_local is used for defining thread-local variables. The header <threads.h>, if supported, defines thread_local as a synonym for that keyword. In C11, <threads.h> also defines a number of functions for retrieving, changing, and destructing a thread-local storage, using names starting with tss_. In C23, thread_local itself becomes a keyword.

C++11 introduces the thread_local keyword which can be used in the following cases

Namespace level (global) variables File static variables Function static variables Static member variables Aside from that, various compiler implementations provide specific ways to declare thread-local variables:

Solaris Studio C/C++, IBM XL C/C++, GNU C, llvm-gcc, Clang, and Intel C++ Compiler (Linux systems) use the syntax: __thread int number; Visual C++, Intel C/C++ (Windows systems), C++Builder, Clang, and Digital Mars C++ use the syntax: __declspec(thread) int number; C++Builder also supports the syntax: int __thread number; On Windows versions before Vista and Server 2008, __declspec(thread) works in DLLs only when those DLLs are bound to the executable, and will not work for those loaded with LoadLibrary() (a protection fault or data corruption may occur).

… excerpt ends here. Continue reading the full article.

Worked examples

Example 1 — a first encounter with Thread-local storage

Start with the simplest possible case. Write down what Thread-local storage claims or describes in one sentence, then invent the smallest concrete situation in which that sentence is true. In computer science, the smallest case is usually a single object, a single equation or a single measurement. Check that every symbol or term in your sentence has a meaning in that case.

Example 2 — changing one variable

Take the situation from Example 1 and change exactly one quantity: double it, halve it, or set it to zero. Predict what should happen to Thread-local storage before you calculate. Comparing your prediction with the result is the fastest way to find out whether you understand the idea or only the words.

Example 3 — an exam-style question

Typical questions about Thread-local storage ask you to (a) state it precisely, (b) apply it to given data, and (c) explain a limitation. Practise writing all three answers in under five minutes; the third part is what separates a full-mark answer from an average one.

Applications of Thread-local storage

In research
Thread-local storage appears in computer science research whenever the underlying quantities have to be modelled precisely. Papers usually cite it as a starting assumption and then explore where it breaks down.
In technology and industry
Engineering practice reuses Thread-local storage in design rules, simulations and safety margins. Knowing the idea lets you read a specification sheet and understand why the numbers look the way they do.
In the classroom
Thread-local storage is common in secondary-school and first-year university syllabi. It links to neighbouring topics Software design patterns, Threads (computing), Variable (computer science), so understanding it makes those chapters shorter.
In everyday life
Look for Thread-local storage outside the textbook — in sport, cooking, traffic, electronics or the sky above you. An example you found yourself is remembered far longer than one you were given.

Affiliate

Preply — study more efficiently by working with a personal tutor. 50% off.

How to study Thread-local storage in 20 minutes

  1. Read the reference excerpt below once, without taking notes.
  2. Close the page and write down what Thread-local storage means in your own words.
  3. Compare your version with the excerpt and mark what you missed.
  4. Work through the three examples above with pen and paper.
  5. Explain Thread-local storage out loud to somebody else — or to Teacher Smith in the lgStudy chat.

Frequently asked questions

What is Thread-local storage in simple terms?

In computer programming, thread-local storage (TLS) is a memory management method that uses static or global memory local to a thread. The concept allows storage of data that appears to be global in a system with separate threads.

Why does Thread-local storage matter?

Because it connects several computer science ideas at once: it gives you a definition you can apply, a quantity you can calculate, and a way to check whether a result is plausible.

How should I study Thread-local storage?

Read the excerpt, restate it from memory, then work through the examples and applications listed on this page. The five-step study plan above takes about twenty minutes.

What does this page cover?

It gives you a compact reference excerpt plus original lgStudy explanations, examples, applications and study material on Thread-local storage.

Tags

  • Software design patterns
  • Threads (computing)
  • Variable (computer science)

Keep exploring