HOME

TheInfoList



OR:

In
computer programming Computer programming or coding is the composition of sequences of instructions, called computer program, programs, that computers can follow to perform tasks. It involves designing and implementing algorithms, step-by-step specifications of proc ...
, thread-local storage (TLS) is a
memory management Memory management (also dynamic memory management, dynamic storage allocation, or dynamic memory allocation) is a form of Resource management (computing), resource management applied to computer memory. The essential requirement of memory manag ...
method that uses static or global
memory Memory is the faculty of the mind by which data or information is encoded, stored, and retrieved when needed. It is the retention of information over time for the purpose of influencing future action. If past events could not be remembe ...
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 In computing, a memory address is a reference to a specific memory location in memory used by both software and hardware. These addresses are fixed-length sequences of digits, typically displayed and handled as unsigned integers. This numeric ...
(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 In electronics and computer science, a reduced instruction set computer (RISC) is a computer architecture designed to simplify the individual instructions given to the computer to accomplish tasks. Compared to the instructions given to a comp ...
machines, the
calling convention In computer science, a calling convention is an implementation-level (low-level) scheme for how subroutines or functions receive parameters from their caller and how they return a result. When some code calls a function, design choices have been ...
often reserves a thread pointer register for this use.


Usage

While the use of
global variable In computer programming, a global variable is a variable with global scope, meaning that it is visible (hence accessible) throughout the program, unless shadowed. The set of all global variables is known as the ''global environment'' or ''global ...
s is generally discouraged in modern programming, some older operating systems such as
UNIX Unix (, ; trademarked as UNIX) is a family of multitasking, multi-user computer operating systems that derive from the original AT&T Unix, whose development started in 1969 at the Bell Labs research center by Ken Thompson, Dennis Ritchie, a ...
were originally designed for uniprocessor hardware and often use global variables to store important values. An example is the
errno errno.h is a header file in the standard library of the C programming language. It defines macros for reporting and retrieving error conditions using the symbol errno (short form for "error number").International Standard for Programming Langu ...
used by many functions of the
C library The C standard library, sometimes referred to as libc, is the standard library for the C programming language, as specified in the ISO C standard.ISO/ IEC (2018). '' ISO/IEC 9899:2018(E): Programming Languages - C §7'' Starting from the origina ...
. 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 A race condition or race hazard is the condition of an electronics, software, or other system where the system's substantive behavior is dependent on the sequence or timing of other uncontrollable events, leading to unexpected or inconsistent ...
, every access to this global variable would have to be protected by a
mutex In computer science, a lock or mutex (from mutual exclusion) is a synchronization primitive that prevents state from being modified or accessed by multiple threads of execution at once. Locks enforce mutual exclusion concurrency control policies, ...
. 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 An application programming interface (API) is a connection between computers or between computer programs. It is a type of software Interface (computing), interface, offering a service to other pieces of software. A document or standard that des ...
(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 In computer operating systems, memory paging is a memory management scheme that allows the physical memory used by a program to be non-contiguous. This also helps avoid the problem of memory fragmentation and requiring compaction to reduce fr ...
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 In computing, POSIX Threads, commonly known as pthreads, is an execution model that exists independently from a programming language, as well as a parallel execution model. It allows a program to control multiple different flows of work that ov ...
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 , if supported, defines thread_local as a synonym for that keyword. Example usage: #include thread_local int foo = 0; In C11, also defines a number of functions for retrieving, changing, and destructing a thread-local storage, using names starting with . In C23, thread_local itself becomes a keyword.
C++11 C++11 is a version of a joint technical standard, ISO/IEC 14882, by the International Organization for Standardization (ISO) and International Electrotechnical Commission (IEC), for the C++ programming language. C++11 replaced the prior vers ...
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 Oracle Developer Studio, formerly named Oracle Solaris Studio, Sun Studio, Sun WorkShop, Forte Developer, and SunPro Compilers, is the Oracle Corporation's flagship software development product for the Solaris and Linux operating systems. It inc ...
C/C++, IBM XL C/C++, GNU C, llvm-gcc,
Clang Clang () is a compiler front end for the programming languages C, C++, Objective-C, Objective-C++, and the software frameworks OpenMP, OpenCL, RenderScript, CUDA, SYCL, and HIP. It acts as a drop-in replacement for the GNU Compiler ...
, and
Intel C++ Compiler Intel oneAPI DPC++/C++ Compiler and Intel C++ Compiler Classic (deprecated icc and icl is in Intel OneAPI HPC toolkit) are Intel’s C, C++, SYCL, and Data Parallel C++ (DPC++) compilers for Intel processor-based systems, available for Wind ...
(Linux systems) use the syntax: *: __thread int number; *
Visual C++ Microsoft Visual C++ (MSVC) is a compiler for the C, C++, C++/CLI and C++/CX programming languages by Microsoft. MSVC is proprietary software; it was originally a standalone product but later became a part of Visual Studio and made available ...
,Visual Studio 2003: Intel C/C++ (Windows systems),
C++Builder C++Builder is a rapid application development (RAD) environment for developing software in the C++ programming language. Originally developed by Borland, it is owned by Embarcadero Technologies, a subsidiary of Idera. C++Builder can compile ...
, 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).


Common Lisp and other dialects

Common Lisp Common Lisp (CL) is a dialect of the Lisp programming language, published in American National Standards Institute (ANSI) standard document ''ANSI INCITS 226-1994 (S2018)'' (formerly ''X3.226-1994 (R1999)''). The Common Lisp HyperSpec, a hyperli ...
provides a feature called
dynamically scoped In computer programming, the scope of a name binding (an association of a name to an entity, such as a Variable (programming), variable) is the part of a Computer program, program where the name binding is valid; that is, where the name can be use ...
variables. Dynamic variables have a binding which is private to the invocation of a function and all of the children called by that function. This abstraction naturally maps to thread-specific storage, and Lisp implementations that provide threads do this. Common Lisp has numerous standard dynamic variables, and so threads cannot be sensibly added to an implementation of the language without these variables having thread-local semantics in dynamic binding. For instance the standard variable *print-base* determines the default radix in which integers are printed. If this variable is overridden, then all enclosing code will print integers in an alternate radix: ;;; function foo and its children will print ;; in hexadecimal: (let ((*print-base* 16)) (foo)) If functions can execute concurrently on different threads, this binding has to be properly thread-local, otherwise each thread will fight over who controls a global printing radix.


D

In D version 2, all static and global variables are thread-local by default and are declared with syntax similar to "normal" global and static variables in other languages. Global variables must be explicitly requested using the ''shared'' keyword: int threadLocal; // This is a thread-local variable. shared int global; // This is a global variable shared with all threads. The ''shared'' keyword works both as the storage class, and as a
type qualifier In the context of programming languages, a type qualifier is a keyword that can be used to annotate a type to instruct the compiler to treat the now ''qualified type'' in a special way. By language C/C++ and C11, there are four type qualifiers i ...
– ''shared'' variables are subject to some restrictions which statically enforce data integrity. To declare a "classic" global variable without these restrictions, the unsafe ''__gshared'' keyword must be used: __gshared int global; // This is a plain old global variable.


Java

In
Java Java is one of the Greater Sunda Islands in Indonesia. It is bordered by the Indian Ocean to the south and the Java Sea (a part of Pacific Ocean) to the north. With a population of 156.9 million people (including Madura) in mid 2024, proje ...
, thread-local variables are implemented by the
class Class, Classes, or The Class may refer to: Common uses not otherwise categorized * Class (biology), a taxonomic rank * Class (knowledge representation), a collection of individuals or objects * Class (philosophy), an analytical concept used d ...
object. ThreadLocal holds variable of type T, which is accessible via get/set methods. For example, ThreadLocal variable holding Integer value looks like this: private static final ThreadLocal myThreadLocalInteger = new ThreadLocal(); At least for Oracle/OpenJDK, this does not use native thread-local storage in spite of OS threads being used for other aspects of Java threading. Instead, each Thread object stores a (non-thread-safe) map of ThreadLocal objects to their values (as opposed to each ThreadLocal having a map of Thread objects to values and incurring a performance overhead).


.NET languages: C# and others

In .NET Framework languages such as C#, static fields can be marked with th
ThreadStatic attribute
class FooBar In .NET Framework 4.0 th
System.Threading.ThreadLocal
class is available for allocating and lazily loading thread-local variables. class FooBar Als
an API
is available for dynamically allocating thread-local variables.


Object Pascal

In
Object Pascal Object Pascal is an extension to the programming language Pascal (programming language), Pascal that provides object-oriented programming (OOP) features such as Class (computer programming), classes and Method (computer programming), methods. T ...
(
Delphi Delphi (; ), in legend previously called Pytho (Πυθώ), was an ancient sacred precinct and the seat of Pythia, the major oracle who was consulted about important decisions throughout the ancient Classical antiquity, classical world. The A ...
) or
Free Pascal Free Pascal Compiler (FPC) is a compiler for the closely related programming-language dialects Pascal and Object Pascal. It is free software released under the GNU General Public License, witexception clausesthat allow static linking against it ...
the ''threadvar'' reserved keyword can be used instead of 'var' to declare variables using the thread-local storage. var mydata_process: integer; threadvar mydata_threadlocal: integer;


Objective-C

In Cocoa,
GNUstep GNUstep is a free software implementation of the Cocoa (formerly OpenStep) Objective-C frameworks, widget toolkit, and application development tools for Unix-like operating systems and Microsoft Windows. It is part of the GNU Project. GNUst ...
, and
OpenStep OpenStep is an object-oriented application programming interface (API) specification developed by NeXT. It provides a framework for building graphical user interfaces (GUIs) and developing software applications. OpenStep was designed to be plat ...
, each NSThread object has a thread-local dictionary that can be accessed through the thread's threadDictionary method. NSMutableDictionary *dict = NSThread currentThreadthreadDictionary]; dict "A key"= @"Some data";


Perl

In
Perl Perl is a high-level, general-purpose, interpreted, dynamic programming language. Though Perl is not officially an acronym, there are various backronyms in use, including "Practical Extraction and Reporting Language". Perl was developed ...
threads were added late in the evolution of the language, after a large body of extant code was already present on the Comprehensive Perl Archive Network (CPAN). Thus, threads in Perl by default take their own local storage for all variables, to minimise the impact of threads on extant non-thread-aware code. In Perl, a thread-shared variable can be created using an attribute: use threads; use threads::shared; my $localvar; my $sharedvar :shared;


PureBasic

In
PureBasic PureBasic is a commercial software, commercially distributed procedural programming, procedural computer programming language and integrated development environment based on BASIC and developed by Fantaisie Software for Microsoft Windows, Windo ...
thread variables are declared with the keywor
Threaded
Threaded Var


Python

In Python version 2.4 or later, ''local'' class in ''threading'' module can be used to create thread-local storage. import threading mydata = threading.local() mydata.x = 1 Multiple instances of ''local'' class can be created to store different sets of variables. Thus, it is not a singleton.


Ruby

Ruby Ruby is a pinkish-red-to-blood-red-colored gemstone, a variety of the mineral corundum ( aluminium oxide). Ruby is one of the most popular traditional jewelry gems and is very durable. Other varieties of gem-quality corundum are called sapph ...
can create/access thread-local variables using []=/[] methods: Thread.current[:user_id] = 1


Rust

Thread-local variables can be created in Rust (programming language), Rust using the macro provided by the Rust standard library: use std::cell::RefCell; use std::thread; thread_local!(static FOO: RefCell = RefCell::new(1)); FOO.with(, f, ); // each thread starts out with the initial value of 1, even though this thread already changed its copy of the thread local value to 2 let t = thread::spawn(move , , ); // wait for the thread to complete and bail out on panic t.join().unwrap(); // original thread retains the original value of 2 despite the child thread changing the value to 3 for that thread FOO.with(, f, );


See also

*
OpenMP OpenMP is an application programming interface (API) that supports multi-platform shared-memory multiprocessing programming in C, C++, and Fortran, on many platforms, instruction-set architectures and operating systems, including Solaris, ...
— Another shared-memory multiprocessing facility which supports per-thread storage via "Data sharing attribute clauses" (see under §Clauses)


References


Bibliography

* *


External links


ELF Handling For Thread-Local Storage
— Document about an implementation in C or C++.
ACE_TSS< TYPE > Class Template Reference
*Article
Use thread-local Storage to Pass Thread Specific Data
by Doug Doedens
Thread-Local Storage
by Lawrence Crowl *Article
It's Not Always Nice To Share
by Walter Bright *Practical ThreadLocal usage in Java: http://www.captechconsulting.com/blogs/a-persistence-pattern-using-threadlocal-and-ejb-interceptors *GCC

*Rust

{{Design Patterns patterns Threads (computing) Variable (computer science) Software design patterns