HOME

TheInfoList



OR:

Thread safety is a computer programming concept applicable to
multi-threaded In computer science, a thread of execution is the smallest sequence of programmed instructions that can be managed independently by a scheduler, which is typically a part of the operating system. The implementation of threads and processes d ...
code. Thread-safe code only manipulates shared data structures in a manner that ensures that all threads behave properly and fulfill their design specifications without unintended interaction. There are various strategies for making thread-safe data structures. A program may execute code in several threads simultaneously in a shared
address space In computing, an address space defines a range of discrete addresses, each of which may correspond to a network host, peripheral device, disk sector, a memory cell or other logical or physical entity. For software programs to save and retrieve s ...
where each of those threads has access to virtually all of the memory of every other thread. Thread safety is a property that allows code to run in multithreaded environments by re-establishing some of the correspondences between the actual flow of control and the text of the program, by means of
synchronization Synchronization is the coordination of events to operate a system in unison. For example, the conductor of an orchestra keeps the orchestra synchronized or ''in time''. Systems that operate with all parts in synchrony are said to be synchronou ...
.


Levels of thread safety

Software libraries can provide certain thread-safety guarantees. For example, concurrent reads might be guaranteed to be thread-safe, but concurrent writes might not be. Whether a program using such a library is thread-safe depends on whether it uses the library in a manner consistent with those guarantees. Different vendors use slightly different terminology for thread-safety: *Thread safe: Implementation is guaranteed to be free of race conditions when accessed by multiple threads simultaneously. *Conditionally safe: Different threads can access different objects simultaneously, and access to shared data is protected from race conditions. *Not thread safe: Data structures should not be accessed simultaneously by different threads. Thread safety guarantees usually also include design steps to prevent or limit the risk of different forms of
deadlock In concurrent computing, deadlock is any situation in which no member of some group of entities can proceed because each waits for another member, including itself, to take action, such as sending a message or, more commonly, releasing a l ...
s, as well as optimizations to maximize concurrent performance. However, deadlock-free guarantees cannot always be given, since deadlocks can be caused by
callbacks In computer programming, a callback or callback function is any reference to executable code that is passed as an argument to another piece of code; that code is expected to ''call back'' (execute) the callback function as part of its job. Thi ...
and violation of architectural layering independent of the library itself.


Implementation approaches

Below we discuss two classes of approaches for avoiding race conditions to achieve thread-safety. The first class of approaches focuses on avoiding shared state and includes: ; Re-entrancy: Writing code in such a way that it can be partially executed by a thread, executed by the same thread, or simultaneously executed by another thread and still correctly complete the original execution. This requires the saving of state information in variables local to each execution, usually on a stack, instead of in static or global variables or other non-local state. All non-local states must be accessed through atomic operations and the data-structures must also be reentrant. ;
Thread-local storage Thread-local storage (TLS) is a computer programming method that uses static or global memory local to a thread. While the use of global variables is generally discouraged in modern programming, legacy operating systems such as UNIX are desi ...
: Variables are localized so that each thread has its own private copy. These variables retain their values across subroutine and other code boundaries and are thread-safe since they are local to each thread, even though the code which accesses them might be executed simultaneously by another thread. ;
Immutable object In object-oriented and functional programming, an immutable object (unchangeable object) is an object whose state cannot be modified after it is created.Goetz et al. ''Java Concurrency in Practice''. Addison Wesley Professional, 2006, Section 3. ...
s: The state of an object cannot be changed after construction. This implies both that only read-only data is shared and that inherent thread safety is attained. Mutable (non-const) operations can then be implemented in such a way that they create new objects instead of modifying existing ones. This approach is characteristic of functional programming and is also used by the ''string'' implementations in Java, C#, and Python. (See
Immutable object In object-oriented and functional programming, an immutable object (unchangeable object) is an object whose state cannot be modified after it is created.Goetz et al. ''Java Concurrency in Practice''. Addison Wesley Professional, 2006, Section 3. ...
.) The second class of approaches are synchronization-related, and are used in situations where shared state cannot be avoided: ;
Mutual exclusion In computer science, mutual exclusion is a property of concurrency control, which is instituted for the purpose of preventing race conditions. It is the requirement that one thread of execution never enters a critical section while a concurren ...
: Access to shared data is ''serialized'' using mechanisms that ensure only one thread reads or writes to the shared data at any time. Incorporation of mutual exclusion needs to be well thought out, since improper usage can lead to side-effects like
deadlock In concurrent computing, deadlock is any situation in which no member of some group of entities can proceed because each waits for another member, including itself, to take action, such as sending a message or, more commonly, releasing a l ...
s,
livelock In concurrent computing, deadlock is any situation in which no member of some group of entities can proceed because each waits for another member, including itself, to take action, such as sending a message or, more commonly, releasing a loc ...
s, and
resource starvation In computer science, resource starvation is a problem encountered in concurrent computing where a process is perpetually denied necessary resources to process its work. Starvation may be caused by errors in a scheduling or mutual exclusion algor ...
. ;
Atomic operations In concurrent programming, an operation (or set of operations) is linearizable if it consists of an ordered list of invocation and response events (event), that may be extended by adding response events such that: # The extended list can be re-e ...
: Shared data is accessed by using atomic operations which cannot be interrupted by other threads. This usually requires using special
machine language In computer programming, machine code is any low-level programming language, consisting of machine language instructions, which are used to control a computer's central processing unit (CPU). Each instruction causes the CPU to perform a ver ...
instructions, which might be available in a
runtime library In computer programming, a runtime library is a set of low-level routines used by a compiler to invoke some of the behaviors of a runtime environment, by inserting calls to the runtime library into compiled executable binary. The runtime envir ...
. Since the operations are atomic, the shared data is always kept in a valid state, no matter how other threads access it. Atomic operations form the basis of many thread locking mechanisms, and are used to implement mutual exclusion primitives.


Examples

In the following piece of Java code, the Java keyword synchronized makes the method thread-safe: class Counter In the
C programming language ''The C Programming Language'' (sometimes termed ''K&R'', after its authors' initials) is a computer programming book written by Brian Kernighan and Dennis Ritchie, the latter of whom originally designed and implemented the language, as well a ...
, each thread has its own stack. However, a static variable is not kept on the stack; all threads share simultaneous access to it. If multiple threads overlap while running the same function, it is possible that a static variable might be changed by one thread while another is midway through checking it. This difficult-to-diagnose
logic error In computer programming, a logic error is a bug in a program that causes it to operate incorrectly, but not to terminate abnormally (or crash). A logic error produces unintended or undesired output or other behaviour, although it may not immed ...
, which may compile and run properly most of the time, is called 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. It becomes a bug when one or more of ...
. One common way to avoid this is to use another shared variable as a "lock" or "mutex" (from mutual exclusion). In the following piece of C code, the function is thread-safe, but not reentrant: # include int increment_counter () In the above, increment_counter can be called by different threads without any problem since a mutex is used to synchronize all access to the shared counter variable. But if the function is used in a reentrant interrupt handler and a second interrupt arises while the mutex is locked, the second routine will hang forever. As interrupt servicing can disable other interrupts, the whole system could suffer. The same function can be implemented to be both thread-safe and reentrant using the lock-free atomics in C++11: # include int increment_counter ()


See also

*
Concurrency control In information technology and computer science, especially in the fields of computer programming, operating systems, multiprocessors, and databases, concurrency control ensures that correct results for concurrent operations are generated, while ...
* Exception safety *
Priority inversion In computer science, priority inversion is a scenario in scheduling in which a high priority task is indirectly superseded by a lower priority task effectively inverting the assigned priorities of the tasks. This violates the priority model that ...
*
ThreadSafe ThreadSafe is a source code analysis tool that identifies application risks and security vulnerabilities associated with concurrency in Java code bases, using whole-program interprocedural analysis. ThreadSafe is used to identify and avoid softw ...


References


External links

* * * *{{cite web, url=http://www.thinkingparallel.com/2006/10/15/a-short-guide-to-mastering-thread-safety/, title=A Short Guide to Mastering Thread-Safety, last=Suess, first=Michael, date=15 October 2006, website=Thinking Parallel, access-date=2012-01-22 Threads (computing) Programming language topics