GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||
GeezerVison is showing en.wikipedia.org — Thread-local storage - Wikipedia
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. UsageWhile 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 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 implementationThe application programming interface (API) function The 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 Apart from the 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 assumes 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 (4 kB 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 Pthreads implementationIn the Pthreads API, memory local to a thread is designated with the term Thread-specific data. The functions In addition Language-specific implementationApart 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 In C11, thread_local int foo = 0; C++11 introduces the
Aside from that, various compiler implementations provide specific ways to declare thread-local variables:
On Windows versions before Vista and Server 2008, Common Lisp and other dialectsCommon 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 ;;; 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. DIn 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 int threadLocal; // This is a thread-local variable. shared int global; // This is a global variable shared with all threads. The __gshared int global; // This is a plain old global variable. JavaIn Java, thread-local variables are implemented by the For example, a thread-local variable holding an integer looks like this (with no initial value): private static final ThreadLocal<Integer> i = new ThreadLocal<>(); To assign an initial value, the factory method private static final ThreadLocal<Integer> i = ThreadLocal.withInitial(() -> 0); Otherwise, if not using lambdas, to assign an initial value, the // Note that, prior to Java 9, an anonymous class cannot infer generics; // the full generic must be spelled out (new ThreadLocal<Integer>() {}) private static final ThreadLocal<Integer> i = new ThreadLocal<>() { @Override protected Integer initialValue() { return 0; } } 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 .NET languages: C# and othersIn .NET Framework languages such as C#, static fields can be marked with the using System; class FooBar { [ThreadStatic] private static int _foo; } In .NET Framework 4.0 the using System.Threading; class FooBar { private static ThreadLocal<int> _foo; }
Object PascalIn Object Pascal (Delphi) or Free Pascal 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-CIn Cocoa, GNUstep, and OpenStep, each NSMutableDictionary *dict = [[NSThread currentThread] threadDictionary]; dict[@"A key"] = @"Some data"; PerlIn 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: use threads; use threads::shared; my $localvar; my $sharedvar :shared; PureBasicIn PureBasic thread variables are declared with the keyword Threaded. Threaded Var PythonIn Python version 2.4 or later, the import threading mydata = threading.local() mydata.x = 1 Multiple instances of Since Python 3.7, the from contextvars import ContextVar user_id: ContextVar[int] = ContextVar("user_id") request_id = ContextVar[str] = ContextVar("request_id") user_id.set(42) request_id.set("abc-123") current_user: int = user_id.get() RubyRuby can create/access thread-local variables using Thread.current[:user_id] = 1 RustThread-local variables can be created in Rust using the use std::cell::RefCell; use std::thread; thread_local!(static FOO: 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 2 let t = 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 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| { assert_eq!(*f.borrow(), 2); }); See alsoReferences
Bibliography
External links
| ||
| You are visitor 01402503 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |