developer tip

스핀 락 대 세마포어

optionbox 2020. 7. 28. 08:27
반응형

스핀 락 대 세마포어


세마포어와 스핀 락의 기본 차이점은 무엇입니까?

스핀 락 대신 세마포어를 언제 사용할까요?


Spinlock과 세마포는 주로 네 가지 점에서 다릅니다.

그들이 무엇 1. 스핀 락은 락의 하나의 가능한 구현 ( "회전") 통화 중 대기에 의해 구현되는, 즉 하나입니다. 세마포어는 잠금의 일반화입니다 (또는 다른 방법으로 잠금은 세마포어의 특수한 경우입니다). 일반적으로, 그러나 반드시 세마포어 너무 다른 프로세스간에 동기화하는 데 사용할 수있는 반면, 스핀 락은 하나 개의 프로세스 내에서만 유효합니다.

잠금은 상호 배제를 위해 작동합니다. 즉, 한 번에 하나의 스레드가 잠금을 획득하고 코드의 "중요 섹션"으로 진행할 수 있습니다. 일반적으로 이것은 여러 스레드가 공유하는 일부 데이터를 수정하는 코드를 의미합니다. 세마포어 카운터를 가지고 있으며, 그 자체에 의해 인수되는 수 하나 개 또는 여러 당신이 그것을 게시하고 (일부 구현에) 최대 허용 값이 무엇인지에 따라 주어진 값 내용에 따라 스레드.

지금까지 잠금은 최대 값이 1 인 세마포어의 특수한 경우로 간주 할 수 있습니다.

2. 작동 방식
위에서 언급 한 것처럼 스핀 락은 잠금이므로 상호 배제 (엄격한 1 대 1) 메커니즘입니다. 일반적으로 원자 방식으로 메모리 위치를 반복적으로 쿼리 및 / 또는 수정하여 작동합니다. 이는 스핀 록을 얻는 것이 "바쁜"작업임을 의미하며, "아무것도"달성하지 않으면 서 CPU주기를 오랫동안 (아마도 영원히) 불 태울 수 있습니다.
이러한 접근 방식의 주된 동기는 컨텍스트 스위치의 오버 헤드가 수백 (또는 수천 번) 회전하는 것과 동일한 오버 헤드를 갖는다는 점입니다. 따라서 몇 번의 회전을 레코딩하여 잠금을 획득 할 수 있다면 전체적으로 매우 잘 될 수 있습니다. 더 효율적입니다. 또한 실시간 응용 프로그램의 경우 스케줄러가 나중에 먼 시간에 다시 돌아 오기를 차단하고 기다리는 것이 허용되지 않을 수 있습니다.

반대로 세마포어는 전혀 회전하지 않거나 아주 짧은 시간 동안 만 회전합니다 (시스템 콜 오버 헤드를 피하기위한 최적화). 세마포어를 확보 할 수없는 경우, 차단되어 실행 준비가 된 다른 스레드에 CPU 시간을 줄입니다. 이것은 물론 스레드가 다시 예약되기 전에 몇 밀리 초가 지난다는 것을 의미 할 수 있지만 이것이 문제가되지 않으면 (보통 그렇지 않은 경우) 매우 효율적인 CPU 절약 접근 방식이 될 수 있습니다.

3. 정체가있을 때 동작 방식
스핀 록 또는 잠금없는 알고리즘이 "일반적으로 더 빠르다"거나 "매우 짧은 작업"에만 유용하다는 것이 일반적으로 오해되고 있습니다 (이상적으로는 동기화 오브젝트를 더 이상 보유하지 않아야 함) 절대적으로 필요한 것보다).
중요한 차이점 중 하나 는 혼잡이있을 때 서로 다른 접근 방식이 어떻게 작동 하는지입니다 .

잘 설계된 시스템은 일반적으로 혼잡이 적거나 없습니다 (모든 스레드가 정확히 동시에 잠금을 획득하려고 시도하는 것은 아님). 예를 들어, 일반적으로 잠금을 획득 한 코드를 작성 하지 않고 네트워크에서 zip 압축 된 데이터의 0.5MB를로드하고 데이터를 디코딩 및 구문 분석 한 다음 공유 참조를 수정합니다 (컨테이너에 데이터 추가 등). 잠금을 해제하기 전에. 대신, 공유 리소스 에 액세스 할 목적으로 만 잠금을 획득합니다 .
이는 임계 섹션 외부보다 임계 섹션 외부에서 상당히 많은 작업이 있음을 의미하므로, 임계 섹션 내부에 스레드가있을 가능성은 상대적으로 낮으므로 잠금을 위해 동시에 스레드에 대해 경합하는 스레드는 거의 없습니다. 물론 모든 이제 다음 두 개의 스레드 (이 경우 같은 시간에 잠금을 획득하려고합니다 없습니다 ! 당신이 잠금이 필요하지 않을 일), 그러나 이것은 오히려 "건강한"시스템의 규칙보다 예외 .

이러한 경우에, 스핀 록이 혼잡이 없다면 스핀 록을 획득하는 오버 헤드는 컨텍스트 스위치를위한 수백 / 수천 사이클 또는 손실을위한 천만 -2,000 만 사이클에 비해 수십 사이클에 불과하기 때문에 스핀 락이 세마포어를 크게 능가한다. 타임 슬라이스의 나머지

반면에, 혼잡이 심하거나 잠금이 오랜 시간 동안 유지되는 경우 (때로는 도움이되지 않을 수도 있습니다!) 스핀 락은 아무 것도 달성하지 못하는 미친 CPU주기를 태울 것입니다.
세마포어 (또는 뮤텍스)는 다른 스레드가 해당 시간 동안 유용한 작업 을 수행 할 수있게하므로이 경우 훨씬 더 나은 선택입니다 . 또는 다른 스레드에 유용한 기능이없는 경우 운영 체제가 CPU를 낮추고 열 / 절약 에너지를 줄일 수 있습니다.

회전하는 스레드가 가능하게 일어날 수없는 상태 변경 (해제 스레드가 예정되어 있지 때까지, 대한 완전한 시간 대기 낭비로 또한, 단일 코어 시스템에서, 스핀 락은 잠금 혼잡의 존재 매우 비효율적 인 것 ISN을 대기중인 스레드가 실행되는 동안 발생하지 않습니다 !). 그러므로 주어진 임의의 경합의 양, 잠금을 획득하는 최상의 경우에서 약 1 1/2 시간 슬라이스를 얻어 좋은 문제 없다 (해제 스레드 가정하면 스케줄링 된 다음이다).

4. 어떻게 구현 되는가
오늘날 세마포어는 일반적으로 sys_futex리눅스에서 랩핑 을한다 (선택적으로 몇 번의 시도 후에 종료되는 스핀 락으로).
스핀 락은 일반적으로 운영 체제에서 제공하는 것을 사용하지 않고 원 자성 작업을 사용하여 구현됩니다. 과거에는 컴파일러 내장 함수 또는 이식 불가능한 어셈블러 명령어를 사용했습니다. 한편 C ++ 11과 C11은 언어의 일부로 원자 연산을 수행하므로 정확한 잠금없는 코드를 작성하는 것이 일반적으로 어렵다는 점을 제외하고는 이제 완전히 휴대 가능하고 (거의) 잠금없는 코드를 구현할 수 있습니다. 고통없는 방법.


간단히 말해서, 세마포어는 "수익성있는"동기화 객체이고, 스핀 락은 'busywait'입니다. (멀티 스레드에서 코드 영역을 보호하는 뮤텍스 또는 가드 또는 모니터 또는 중요한 섹션과 달리 여러 스레드를 동기화한다는 점에서 세마포어에는 약간 더 있습니다)

더 많은 상황에서 세마포어를 사용하지만 아주 짧은 시간 동안 잠그는 스핀 락을 사용하십시오-특히 많이 잠그면 잠그는 비용이 있습니다. 이러한 경우 보호 된 리소스가 잠금 해제 될 때까지 잠시 동안 스핀 록하는 것이 더 효율적일 수 있습니다. 너무 오래 회전하면 성능이 저하 될 수 있습니다.

일반적으로 스레드 양자보다 길게 회전하는 경우 세마포어를 사용해야합니다.


Over and above what Yoav Aviram and gbjbaanb said, the other key point used to be that you would never use a spin-lock on a single-CPU machine, whereas a semaphore would make sense on such a machine. Nowadays, you are frequently hard-pressed to find a machine without multiple cores, or hyperthreading, or equivalent, but in the circumstances that you have just a single CPU, you should use semaphores. (I trust the reason is obvious. If the single CPU is busy waiting for something else to release the spin-lock, but it is running on the only CPU, the lock is unlikely to be released until the current process or thread is preempted by the O/S, which might take a while and nothing useful happens until the preemption occurs.)


From Linux Device Drivers by Rubinni

Unlike semaphores, spinlocks may be used in code that cannot sleep, such as interrupt handlers


I am not a kernel expert but here are few points:

Even uniprocessor machine can use spin-locks if kernel preemption is enabled while compiling the kernel. If kernel preemption is disabled then spin-lock (perhaps) expands to a void statement.

Also, when we are trying to compare Semaphore vs Spin-lock, I believe semaphore refers to the one used in kernel - NOT the one used for IPC (userland).

Basically, spin-lock shall be used if critical section is small (smaller than the overhead of sleep/wake-up) and critical section does not call anything that can sleep! A semaphore shall be used if critical section is bigger and it can sleep.

Raman Chalotra.


Spinlock refers to an implementation of inter-thread locking using machine dependent assembly instructions (such as test-and-set). It is called a spinlock because the thread simply waits in a loop ("spins") repeatedly checking until the lock becomes available (busy wait). Spinlocks are used as a substitute for mutexes, which are a facility supplied by operating systems (not the CPU), because spinlocks perform better, if locked for a short period of time.

A Semaphor is a facility supplied by operating systems for IPC, therefor it's main purpose is inter-process-communication. Being a facility supplied by the operating system it's performance will not be as good as that of a spinlock for inter-thead locking (although possible). Semaphores are better for locking for longer periods of time.

That said - implementing splinlocks in assembly is tricky, and not portable.


I would like to add my observations, more general and not very Linux-specific.

Depending on the memory architecture and the processor capabilities, you might need a spin-lock in order to implement a semaphore on a multi-core or a multiprocessor system, because in such systems a race condition might occur when two or more threads/processes want to acquire a semaphore.

Yes, if your memory architecture offers the locking of a memory section by one core/processor delaying all other accesses, and if your processors offers a test-and-set, you may implement a semaphore without a spin-lock (but very carefully!).

However, as simple/cheap multi-core systems are designed (I'm working in embedded systems), not all memory architectures support such multi-core/multiprocessor features, only test-and-set or equivalent. Then an implementation could be as follows:

  • acquire the spin-lock (busy waiting)
  • try to acquire the semaphore
  • release the spin-lock
  • if the semaphore was not successfully acquired, suspend the current thread until the semaphore is released; otherwise continue with the critical section

Releasing the semaphore would need to be implemented as follows:

  • acquire the spin-lock
  • release the semaphore
  • release the spin-lock

Yes, and for simple binary semaphores on an OS-level it would be possible to use only a spin-lock as replacement. But only if the code-sections to be protected are really very small.

As said before, if and when you implement your own OS, make sure to be careful. Debugging such errors is fun (my opinion, not shared by many), but mostly very tedious and difficult.


A "mutex" (or "mutual exclusion lock") is a signal that two or more asynchronous processes can use to reserve a shared resource for exclusive use. The first process that obtains ownership of the "mutex" also obtains ownership of the shared resource. Other processes must wait for for the first process to release it's ownership of the "mutex" before they may attempt to obtain it.

The most common locking primitive in the kernel is the spinlock. The spinlock is a very simple single-holder lock. If a process attempts to acquire a spinlock and it is unavailable, the process will keep trying (spinning) until it can acquire the lock. This simplicity creates a small and fast lock.


Spinlock is used if and only if you are pretty certain that your expected result will happen very shortly, before your thread's execution slice time expires.

Example: In device driver module, The driver writes "0" in hardware Register R0 and now it needs to wait for that R0 register to become 1. The H/W reads the R0 and does some work and writes "1" in R0. This is generally quick(in micro seconds). Now spinning is much better than going to sleep and interrupted by the H/W. Of course, while spinning, H/W failure condition needs to be taken care!

There is absolutely no reason for a user application to spin. It doesn't make sense. You are going to spin for some event to happen and that event needs to be completed by another user level application which is never guaranteed to happen within quick time frame. So, I will not spin at all in user mode. I better to sleep() or mutexlock() or semaphore lock() in user mode.


From what is the difference between spin locks and semaphores? by Maciej Piechotka:

Both manage a limited resource. I'll first describe difference between binary semaphore (mutex) and spin lock.

Spin locks perform a busy wait - i.e. it keeps running loop:

while (try_acquire_resource ()); 
 ...  
release();

It performs very lightweight locking/unlocking but if the locking thread will be preempted by other which will try to access the same resouce the second one will simply try to acquitre resource untill it run out of it CPU quanta.
On the other hand mutex behave more like:

if (!try_lock()) {
    add_to_waiting_queue ();
    wait();
}
...
process *p = get_next_process_from_waiting_queue ();
p->wakeUp ();

Hence if the thread will try to acquire blocked resource it will be suspended till it will be avaible for it. Locking/unlocking is much more heavy but the waiting is 'free' and 'fair'.

Semaphore is a lock that is allowed to be used multiple (known from initialization) number of times - for example 3 threads are allowed to simultainusly hold the resource but no more. It is used for example in producer/consumer problem or in general in queues:

P(resources_sem)
resource = resources.pop()
...
resources.push(resources)
V(resources_sem)

Difference between semaphore, mutex & spinlock?

Locking in Linux


spin lock can be held by only one process while semaphore can be held by one or more processes. Spin lock wait until the process releases a lock and then acquires a lock. Semaphore is sleeping lock i.e waits and goes to sleep.

참고URL : https://stackoverflow.com/questions/195853/spinlock-versus-semaphore

반응형