Thread safety
|
|
This article includes a list of references, related reading or external links, but its sources remain unclear because it lacks inline citations. Please improve this article by introducing more precise citations. (June 2009) |
Thread safety is a computer programming concept applicable in the context of multi-threaded programs. A piece of code is thread-safe if it only manipulates shared data structures in a manner that guarantees safe execution by multiple threads at the same time. There are various strategies for making thread-safe data structures.[1][2]
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 or not a program using such a library is thread-safe depends on whether it uses the library in a manner consistent with those guarantees.
A key challenge in multi-threaded programming, thread safety was not a concern for most application developers until the 1990s when operating systems began to expose multiple threads for code execution. Today, a program may execute code on several threads simultaneously in a shared address space where each of those threads have access to virtually all of the memory of every other thread. Thus the flow of control and the sequence of accesses to data often have little relation to what would be reasonably expected by looking at the text of the program, violating the principle of least astonishment.[citation needed] Thread safety is a property that allows code to run in multi-threaded environments by re-establishing some of the correspondences between the actual flow of control and the text of the program, by means of synchronization.
Contents |
[edit] Identification
It is not easy to determine whether or not a piece of code is thread-safe. However, there are several indicators that suggest the need for careful examination to see if it is unsafe:
- accessing global variables or the heap
- allocating/reallocating/freeing resources that have global scope (files, sub-processes, pipes, etc.)
- indirect accesses through handles or pointers
- any visible side-effect (e.g., access to volatile variables in the C programming language)
All this can be subsumed under manipulation of global state, which is not neccessarily restricted to a single program/process.
[edit] Implementation
There are a few ways to achieve thread safety:
- Re-entrancy
- Writing code in such a way that it can be partially executed by a thread, reexecuted 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. There are still some rare cases where non-local state can be used in a reentrant function, if the access is done through atomic operations and the data-structure is reentrant.
- Mutual exclusion or Process synchronization
- Access to shared data is serialized using mechanisms that ensure only one thread reads or writes the shared data at any time. Great care is required if a piece of code accesses multiple shared pieces of data—problems include race conditions, deadlocks, livelocks and starvation.
- Thread-local storage
- 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.
- Atomic operations
- Shared data are accessed by using atomic operations which cannot be interrupted by other threads. This usually requires using special machine language instructions, which might be available in a runtime library. Since the operations are atomic, the shared data are always kept in a valid state, no matter what other threads access it. Atomic operations form the basis of many thread locking mechanisms.
[edit] Examples
In the following piece of C code, the function is thread-safe, but not reentrant:
int function() { mutex_lock(); ... function body ... mutex_unlock(); }
In the above, function can be called by different threads without any problem. But if the function is used in a reentrant interrupt handler and a second interrupt arises inside the function, the second routine will hang forever. As interrupt servicing can disable other interrupts, the whole system could suffer.
[edit] Concurrent programming
Note that a piece of code can be thread safe, and yet unable to run at the same time that some other piece of code is running. A trivial example of that is when that other piece of code restarts the computer. The following piece of C code, presents a less obvious situation where a thread is using a file that another thread or process might delete.
int function() { char *filename = "/etc/config"; FILE *config; if (file_exist(filename)) { config = fopen(filename); } }
In the above, the function is thread-safe, as it can be called from any number of threads and will not fail. But all the calls should be in a controlled environment. If executed in a multi-process environment, or if the file is stored on a network-shared drive, there is no warranty that it won't be deleted.
[edit] Difficulties
One approach to making data thread-safe that combines several of the above elements is to make changes atomically to update the shared data. Thus, most of the code is concurrent, and little time is spent serialized.
[edit] See also
- Control flow analysis
- Priority inversion
- Concurrency control
- Exception safety
- Communicating sequential processes - a technique for analyzing concurrency
[edit] References
- ^ Kerrisk, Michael (2010). The Linux Programing Interface. No Starch Press. p. 655.
- ^ "Multithreaded Programming Guide". Oracle Corporation. November 2010. http://download.oracle.com/docs/cd/E19963-01/html/821-1601/docinfo.html. "A procedure is thread safe when the procedure is logically correct when executed simultaneously by several threads."
[edit] External links
- Thread-safe Tcl Extensions
- Java Q&a Experts (20 April 1999). "Thread-safe design (4/20/99)". JavaWorld.com. http://www.javaworld.com/javaworld/javaqa/1999-04/01-threadsafe.html. Retrieved 2012-01-22.
- Venners, Bill (1 August 1998). "Design for thread safety". JavaWorld.com. http://www.javaworld.com/javaworld/jw-08-1998/jw-08-techniques.html. Retrieved 2012-01-22.
- Bridgham, Phillip (12 July 2004). "Write thread-safe servlets". JavaWorld.com. http://www.javaworld.com/javaworld/jw-07-2004/jw-0712-threadsafe.html. Retrieved 2012-01-22.
- Suess, Michael (15 October 2006). "A Short Guide to Mastering Thread-Safety". Thinking Parallel. http://www.thinkingparallel.com/2006/10/15/a-short-guide-to-mastering-thread-safety/. Retrieved 2012-01-22.