This article needs additional citations for verification .(December 2012) |
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.
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.
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. [1] 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.
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).
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).
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. Example usage:
#include<threads.h>thread_localintfoo=0;
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. [2]
C++11 introduces the thread_local
[3] keyword which can be used in the following cases
Aside from that, various compiler implementations provide specific ways to declare thread-local variables:
__thread int number;
__declspec(thread) int number;
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). [10]
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.
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:
intthreadLocal;// This is a thread-local variable.sharedintglobal;// This is a global variable shared with all threads.
The shared keyword works both as the storage class, and as a type qualifier – shared variables are subject to some restrictions which statically enforce data integrity. [13] To declare a "classic" global variable without these restrictions, the unsafe __gshared keyword must be used: [14]
__gsharedintglobal;// This is a plain old global variable.
In Java, thread-local variables are implemented by the ThreadLocal
class object. [15] ThreadLocal holds variable of type T, [15] which is accessible via get/set methods. For example, ThreadLocal variable holding Integer value looks like this:
privatestaticfinalThreadLocal<Integer>myThreadLocalInteger=newThreadLocal<Integer>();
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). [16]
In .NET Framework languages such as C#, static fields can be marked with the ThreadStatic attribute: [17] : 898
classFooBar{[ThreadStatic]privatestaticint_foo;}
In .NET Framework 4.0 the System.Threading.ThreadLocal<T> class is available for allocating and lazily loading thread-local variables. [17] : 899
classFooBar{privatestaticSystem.Threading.ThreadLocal<int>_foo;}
Also an API is available for dynamically allocating thread-local variables. [17] : 899–890
In Object Pascal (Delphi) or Free Pascal the threadvar reserved keyword can be used instead of 'var' to declare variables using the thread-local storage.
varmydata_process:integer;threadvarmydata_threadlocal:integer;
In Cocoa, GNUstep, and OpenStep, each NSThread
object has a thread-local dictionary that can be accessed through the thread's threadDictionary
method.
NSMutableDictionary*dict=[[NSThreadcurrentThread]threadDictionary];dict[@"A key"]=@"Some data";
In Perl 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:
usethreads;usethreads::shared;my$localvar;my$sharedvar:shared;
In PureBasic thread variables are declared with the keyword Threaded.
Threaded Var
In Python version 2.4 or later, local class in threading module can be used to create thread-local storage.
importthreadingmydata=threading.local()mydata.x=1
Multiple instances of local class can be created to store different sets of variables. [18] Thus, it is not a singleton.
Ruby can create/access thread-local variables using []=
/[]
methods:
Thread.current[:user_id]=1
Thread-local variables can be created in Rust using the thread_local!
macro provided by the Rust standard library:
usestd::cell::RefCell;usestd::thread;thread_local!(staticFOO: RefCell<u32>=RefCell::new(1));FOO.with(|f|{assert_eq!(*f.borrow(),1);*f.borrow_mut()=2;});// each thread starts out with the initial value of 1, even though this thread already changed its copy of the thread local value to 2lett=thread::spawn(move||{FOO.with(|f|{assert_eq!(*f.borrow(),1);*f.borrow_mut()=3;});});// wait for the thread to complete and bail out on panict.join().unwrap();// original thread retains the original value of 2 despite the child thread changing the value to 3 for that threadFOO.with(|f|{assert_eq!(*f.borrow(),2);});
In multi-threaded computer programming, a function is thread-safe when it can be invoked or accessed concurrently by multiple threads without causing unexpected behavior, race conditions, or data corruption. As in the multi-threaded context where a program executes several threads simultaneously in a shared address space and each of those threads has access to every other thread's memory, thread-safe functions need to ensure that all those threads behave properly and fulfill their design specifications without unintended interaction.
In programming languages, a closure, also lexical closure or function closure, is a technique for implementing lexically scoped name binding in a language with first-class functions. Operationally, a closure is a record storing a function together with an environment. The environment is a mapping associating each free variable of the function with the value or reference to which the name was bound when the closure was created. Unlike a plain function, a closure allows the function to access those captured variables through the closure's copies of their values or references, even when the function is invoked outside their scope.
In software engineering, double-checked locking is a software design pattern used to reduce the overhead of acquiring a lock by testing the locking criterion before acquiring the lock. Locking occurs only if the locking criterion check indicates that locking is required.
D, also known as dlang, is a multi-paradigm system programming language created by Walter Bright at Digital Mars and released in 2001. Andrei Alexandrescu joined the design and development effort in 2007. Though it originated as a re-engineering of C++, D is now a very different language. As it has developed, it has drawn inspiration from other high-level programming languages. Notably, it has been influenced by Java, Python, Ruby, C#, and Eiffel.
In computer programming, a global variable is a variable with global scope, meaning that it is visible throughout the program, unless shadowed. The set of all global variables is known as the global environment or global state. In compiled languages, global variables are generally static variables, whose extent (lifetime) is the entire runtime of the program, though in interpreted languages, global variables are generally dynamically allocated when declared, since they are not known ahead of time.
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, AIX, FreeBSD, HP-UX, Linux, macOS, and Windows. It consists of a set of compiler directives, library routines, and environment variables that influence run-time behavior.
The syntax of the C programming language is the set of rules governing writing of software in C. It is designed to allow for programs that are extremely terse, have a close relationship with the resulting object code, and yet provide relatively high-level data abstraction. C was the first widely successful high-level language for portable operating-system development.
In computer science, a union is a value that may have any of multiple representations or formats within the same area of memory; that consists of a variable that may hold such a data structure. Some programming languages support a union type for such a data type. In other words, a union type specifies the permitted types that may be stored in its instances, e.g., float
and integer
. In contrast with a record, which could be defined to contain both a float and an integer; a union would hold only one at a time.
In computer science and software engineering, busy-waiting, busy-looping or spinning is a technique in which a process repeatedly checks to see if a condition is true, such as whether keyboard input or a lock is available. Spinning can also be used to generate an arbitrary time delay, a technique that was necessary on systems that lacked a method of waiting a specific length of time. Processor speeds vary greatly from computer to computer, especially as some processors are designed to dynamically adjust speed based on current workload. Consequently, spinning as a time-delay technique can produce inconsistent or even unpredictable results on different systems unless code is included to determine the time a processor takes to execute a "do nothing" loop, or the looping code explicitly checks a real-time clock.
In class-based, object-oriented programming, a constructor is a special type of function called to create an object. It prepares the new object for use, often accepting arguments that the constructor uses to set required member variables.
In computer programming, a value is said to be volatile if it can be read or modified asynchronously by something other than the current thread of execution. The value of a volatile
variable may spontaneously change for reasons such as: sharing values with other threads; sharing values with asynchronous signal handlers; accessing hardware devices via memory-mapped I/O . Support for these use cases varies considerably among the several programming language that have the volatile
keyword. Volatility can have implications regarding function calling conventions and how variables are stored, accessed and cached.
In computer programming, a static variable is a variable that has been allocated "statically", meaning that its lifetime is the entire run of the program. This is in contrast to shorter-lived automatic variables, whose storage is stack allocated and deallocated on the call stack; and in contrast to dynamically allocated objects, whose storage is allocated and deallocated in heap memory.
In some programming languages, const is a type qualifier that indicates that the data is read-only. While this can be used to declare constants, const in the C family of languages differs from similar constructs in other languages in that it is part of the type, and thus has complicated behavior when combined with pointers, references, composite data types, and type-checking. In other languages, the data is not in a single memory location, but copied at compile time for each use. Languages which use it include C, C++, D, JavaScript, Julia, and Rust.
A class in C++ is a user-defined type or data structure declared with any of the keywords class
, struct
or union
that has data and functions as its members whose access is governed by the three access specifiers private, protected or public. By default access to members of a C++ class declared with the keyword class
is private. The private members are not accessible outside the class; they can be accessed only through member functions of the class. The public members form an interface to the class and are accessible outside the class.
The C and C++ programming languages are closely related but have many significant differences. C++ began as a fork of an early, pre-standardized C, and was designed to be mostly source-and-link compatible with C compilers of the time. Due to this, development tools for the two languages are often integrated into a single product, with the programmer able to specify C or C++ as their source language.
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 version of the C++ standard, named C++03, and was later replaced by C++14. The name follows the tradition of naming language versions by the publication year of the specification, though it was formerly named C++0x because it was expected to be published before 2010.
In computer programming, a pure function is a function that has the following properties:
In computer programming, a variable-length array (VLA), also called variable-sized or runtime-sized, is an array data structure whose length is determined at runtime, instead of at compile time. In the language C, the VLA is said to have a variably modified data type that depends on a value.
C++14 is a version of the ISO/IEC 14882 standard for the C++ programming language. It is intended to be a small extension over C++11, featuring mainly bug fixes and small improvements, and was replaced by C++17. Its approval was announced on August 18, 2014. C++14 was published as ISO/IEC 14882:2014 in December 2014.
Objective-C is a high-level general-purpose, object-oriented programming language that adds Smalltalk-style message passing (messaging) to the C programming language. Originally developed by Brad Cox and Tom Love in the early 1980s, it was selected by NeXT for its NeXTSTEP operating system. Due to Apple macOS’s direct lineage from NeXTSTEP, Objective-C was the standard language used, supported, and promoted by Apple for developing macOS and iOS applications from 1997, when Apple purchased NeXT until the introduction of the Swift language in 2014.
This document describes the language extensions provided by Clang. In addition to the language extensions listed here, Clang aims to support a broad range of GCC extensions. Please see the GCC manual for more information on these extensions.