词条 | Spinlock |
释义 |
In software engineering, a spinlock is a lock which causes a thread trying to acquire it to simply wait in a loop ("spin") while repeatedly checking if the lock is available. Since the thread remains active but is not performing a useful task, the use of such a lock is a kind of busy waiting. Once acquired, spinlocks will usually be held until they are explicitly released, although in some implementations they may be automatically released if the thread being waited on (the one which holds the lock) blocks, or "goes to sleep". Because they avoid overhead from operating system process rescheduling or context switching, spinlocks are efficient if threads are likely to be blocked for only short periods. For this reason, operating-system kernels often use spinlocks. However, spinlocks become wasteful if held for longer durations, as they may prevent other threads from running and require rescheduling. The longer a thread holds a lock, the greater the risk that the thread will be interrupted by the OS scheduler while holding the lock. If this happens, other threads will be left "spinning" (repeatedly trying to acquire the lock), while the thread holding the lock is not making progress towards releasing it. The result is an indefinite postponement until the thread holding the lock can finish and release it. This is especially true on a single-processor system, where each waiting thread of the same priority is likely to waste its quantum (allocated time where a thread can run) spinning until the thread that holds the lock is finally finished. Implementing spin locks correctly offers challenges because programmers must take into account the possibility of simultaneous access to the lock, which could cause race conditions. Generally, such an implementation is possible only with special assembly-language instructions, such as atomic test-and-set operations and cannot be easily implemented in programming languages not supporting truly atomic operations.[1] On architectures without such operations, or if high-level language implementation is required, a non-atomic locking algorithm may be used, e.g. Peterson's algorithm. However, such an implementation may require more memory than a spinlock, be slower to allow progress after unlocking, and may not be implementable in a high-level language if out-of-order execution is allowed. Example implementationThe following example uses x86 assembly language to implement a spinlock. It will work on any Intel 80386 compatible processor.
locked: ; The lock variable. 1 = locked, 0 = unlocked. spin_lock: xchg eax, [locked] ; Atomically swap the EAX register with ; the lock variable. ; This will always store 1 to the lock, leaving ; the previous value in the EAX register. test eax, eax ; Test EAX with itself. Among other things, this will ; set the processor's Zero Flag if EAX is 0. ; If EAX is 0, then the lock was unlocked and ; we just locked it. ; Otherwise, EAX is 1 and we didn't acquire the lock. jnz spin_lock ; Jump back to the MOV instruction if the Zero Flag is ; not set; the lock was previously locked, and so ; we need to spin until it becomes unlocked. ret ; The lock has been acquired, return to the calling ; function. spin_unlock: xchg eax, [locked] ; Atomically swap the EAX register with ; the lock variable. Significant optimizationsThe simple implementation above works on all CPUs using the x86 architecture. However, a number of performance optimizations are possible: On later implementations of the x86 architecture, spin_unlock can safely use an unlocked MOV instead of the slower locked XCHG. This is due to subtle memory ordering rules which support this, even though MOV is not a full memory barrier. However, some processors (some Cyrix processors, some revisions of the Intel Pentium Pro (due to bugs), and earlier Pentium and i486 SMP systems) will do the wrong thing and data protected by the lock could be corrupted. On most non-x86 architectures, explicit memory barrier or atomic instructions (as in the example) must be used. On some systems, such as IA-64, there are special "unlock" instructions which provide the needed memory ordering. To reduce inter-CPU bus traffic, code trying to acquire a lock should loop reading without trying to write anything until it reads a changed value. Because of MESI caching protocols, this causes the cache line for the lock to become "Shared"; then there is remarkably no bus traffic while a CPU waits for the lock. This optimization is effective on all CPU architectures that have a cache per CPU, because MESI is so widespread. AlternativesThe primary disadvantage of a spinlock is that, while waiting to acquire a lock, it wastes time that might be productively spent elsewhere. There are two ways to avoid this:
Most operating systems (including Solaris, Mac OS X and FreeBSD) use a hybrid approach called "adaptive mutex". The idea is to use a spinlock when trying to access a resource locked by a currently-running thread, but to sleep if the thread is not currently running. (The latter is always the case on single-processor systems.)[3] OpenBSD attempted to replace spinlocks with ticket locks which enforced first-in-first-out behaviour, however this resulted in more CPU usage in the kernel and larger applications, such as Firefox, becoming much slower.[4][5]See also
References1. ^{{cite book | last= Silberschatz| first= Abraham |author2= Galvin, Peter B. | title=Operating System Concepts | edition=Fourth | year=1994 | publisher=Addison-Wesley | pages=176–179 | isbn= 0-201-59292-4 }} 2. ^{{cite web |url=https://lwn.net/Articles/365863/ |title=Spinlock naming resolved |author=Jonathan Corbet |date=9 December 2009 |publisher=LWN.net |accessdate=14 May 2013}} 3. ^{{cite book | last=Silberschatz| first=Abraham |author2=Galvin, Peter B. | title=Operating System Concepts | edition=Fourth | year=1994 | publisher=Addison-Wesley | pages=198 | isbn=0-201-59292-4}} 4. ^{{cite web|url=http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/lib/librthread/rthread.c?rev=1.71&content-type=text/x-cvsweb-markup|title=src/lib/librthread/rthread.c - Revision 1.71|date=2013-06-01|author=Ted Unangst}} 5. ^{{cite web|url=https://lobste.rs/c/6cybxn|title=tedu comment on Locking in WebKit - Lobsters|date=2016-05-06|author=Ted Unangst}} External links
2 : Concurrency control algorithms|Programming constructs |
随便看 |
|
开放百科全书收录14589846条英语、德语、日语等多语种百科知识,基本涵盖了大多数领域的百科知识,是一部内容自由、开放的电子版国际百科全书。