HOME

TheInfoList



OR:

Thread-local storage (TLS) is a computer programming method that uses
static Static may refer to: Places *Static Nunatak, a nunatak in Antarctica United States * Static, Kentucky and Tennessee *Static Peak, a mountain in Wyoming **Static Peak Divide, a mountain pass near the peak Science and technology Physics *Static el ...
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 remembered ...
local to a thread. 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 ...
s is generally discouraged in modern programming, legacy operating systems such as
UNIX Unix (; trademarked as UNIX) is a family of multitasking, multiuser 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, an ...
are designed for uniprocessor hardware and require some additional mechanism to retain the semantics of pre- reentrant APIs. An example of such situations is where functions use a global variable to set an error condition (for example the global variable
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 for "error number").International Standard for Programming Language C ( ...
used by many functions of the C library). If errno were a global 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 like it is global, but in fact exists once per thread—i.e., it lives in 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 Sequential logic, dependent on the sequence or timing of other uncontrollable events. It becomes a software ...
, 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: a mechanism that enforces limits on access to a resource when there are many threads of execution. A lock is designed to enforce a mutual exclusion concur ...
. Alternatively, each thread might accumulate into a thread-local variable (that, by definition, cannot be read from or written to from other threads, implying that there can be no race conditions). Threads then only have to synchronise a final accumulation from their own thread-local variable into a single, truly global variable. 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 used at various levels by software and hardware. Memory addresses are fixed-length sequences of digits conventionally displayed and manipulated as unsigned integers. ...
(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 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 bee ...
often reserves a thread pointer register for this use.


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. TlsAlloc returns an index to this table, unique per address space, for each call. Each thread has its own copy of the thread-local storage table. Hence, each thread can independently use TlsSetValue(index) 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 by which a computer stores and retrieves data from Computer data storage#Secondary storage, secondary storage for use in Computer data storage#Primary storage, main mem ...
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 POSIX Threads, commonly known as pthreads, is an execution model that exists independently from a language, as well as a parallel execution model. It allows a program to control multiple different flows of work that overlap in time. Each flow o ...
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 C11, C.XI, C-11 or C.11 may refer to: Transport * C-11 Fleetster, a 1920s American light transport aircraft for use of the United States Assistant Secretary of War * Fokker C.XI, a 1935 Dutch reconnaissance seaplane * LET C-11, a license-build var ...
, the keyword _Thread_local is used to define thread-local variables. The header , if supported, defines thread_local as a synonym for that keyword. Example usage: #include thread_local int foo = 0;
C++11 C++11 is a version of the ISO/ IEC 14882 standard for the C++ programming language. C++11 replaced the prior version of the C++ standard, called C++03, and was later replaced by C++14. The name follows the tradition of naming language versions b ...
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,
Clang Clang is a compiler front end for the C, C++, Objective-C, and Objective-C++ programming languages, as well as the OpenMP, OpenCL, RenderScript, CUDA, and HIP frameworks. It acts as a drop-in replacement for the GNU Compiler Collection ...
and
Intel C++ Compiler Intel oneAPI DPC++/C++ Compiler and Intel C++ Compiler Classic are Intel’s C, C++, SYCL, and Data Parallel C++ (DPC++) compilers for Intel processor-based systems, available for Windows, Linux, and macOS operating systems. Overview Intel ...
(Linux systems) use the syntax: *: __thread int number; *
Visual C++ Microsoft Visual C++ (MSVC) is a compiler for the C, C++ 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 in both tri ...
,Visual Studio 2003: Intel C/C++ (Windows systems),
C++Builder C++Builder is a rapid application development (RAD) environment, originally developed by Borland and owned by Embarcadero Technologies (a subsidiary of Idera), for writing programs in the C++ programming language currently targeting Windows (bo ...
, 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 maybe other dialects)

Common Lisp provides a feature called dynamically scoped 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 C, C++, and D programming languages, a type qualifier is a keyword that is applied to a type, resulting in a ''qualified type.'' For example, const int is a qualified type representing a constant integer, while int is the corresponding u ...
– ''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 (; id, Jawa, ; jv, ꦗꦮ; su, ) is one of the Greater Sunda Islands in Indonesia. It is bordered by the Indian Ocean to the south and the Java Sea to the north. With a population of 151.6 million people, Java is the world's mos ...
, thread-local variables are implemented by the class 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 The .NET Framework (pronounced as "''dot net"'') is a proprietary software framework developed by Microsoft that runs primarily on Microsoft Windows. It was the predominant implementation of the Common Language Infrastructure (CLI) until bein ...
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 that provides object-oriented programming (OOP) features such as classes and methods. The language was originally developed by Apple Computer as ''Clascal'' for the Lisa Worksh ...
( Delphi) 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 its ...
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. GNUste ...
, and
OpenStep OpenStep is a defunct object-oriented application programming interface (API) specification for a legacy object-oriented operating system, with the basic goal of offering a NeXTSTEP-like environment on non-NeXTSTEP operating systems. OpenStep wa ...
, 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 family of two high-level, general-purpose, interpreted, dynamic programming languages. "Perl" refers to Perl 5, but from 2000 to 2019 it also referred to its redesigned "sister language", Perl 6, before the latter's name was offic ...
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 commercially distributed procedural computer programming language and integrated development environment based on BASIC and developed by Fantaisie Software for Windows, Linux, and macOS. An Amiga version is available, although ...
thread variables are declared with the keywor
Threaded
Threaded Var


Python

In
Python Python may refer to: Snakes * Pythonidae, a family of nonvenomous snakes found in Africa, Asia, and Australia ** ''Python'' (genus), a genus of Pythonidae found in Africa and Asia * Python (mythology), a mythical serpent Computing * Python (pro ...
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


Ruby

Ruby A 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 ...
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 (Open Multi-Processing) 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 syst ...
Parallel processor support for certain hardware *
Shared memory In computer science, shared memory is memory that may be simultaneously accessed by multiple programs with an intent to provide communication among them or avoid redundant copies. Shared memory is an efficient means of passing data between progr ...
Access to memory pages and configuration of (cpu and or kernel supported, if supported) * Context switch Also called task switching, threads, pages are hardware accelerated and or kernel provided *
Semaphore (programming) In computer science, a semaphore is a variable or abstract data type used to control access to a common resource by multiple threads and avoid critical section problems in a concurrent system such as a multitasking operating system. Semaph ...
LOCK, if (cpu) doesn't support multi-ported memory sufficiently (prevent cpu freeze)


References


External links


ELF Handling For Thread-Local Storage
— Document about an implementation in C or
C++ C++ (pronounced "C plus plus") is a high-level general-purpose programming language created by Danish computer scientist Bjarne Stroustrup as an extension of the C programming language, or "C with Classes". The language has expanded significan ...
.
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 Walter G. Bright is an American computer programmer who created the D programming language, the Zortech C++ compiler, and the ''Empire'' computer game. Early life and education Bright is the son of the United States Air Force pilot Charles D. ...
*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