自旋锁与信号量 [英] Spinlock versus Semaphore

查看:194
本文介绍了自旋锁与信号量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

什么是信号量与放之间的基本差异;自旋锁? &安培;在什么情况下最好还是条件下,我们可以使用这些。

What is the basic differences between Semaphores & Spinlock? & In what best situations or conditions, we can use these.

推荐答案

自旋锁和信号量的不同主要表现在四个方面:

Spinlock and semaphore differ mainly in four things:

1。他们是什么结果
A 自旋锁的是一个可能实现的锁,即一个由忙等待(纺)来实现。信号量是一个锁的一般化(或其他方式,锁是信号量的一种特殊情况)。一般,但不一定的,自旋锁是只有一个进程内有效,而信号量可以使用不同的进程之间进行同步,也

1. What they are
A spinlock is one possible implementation of a lock, namely one that is implemented by busy waiting ("spinning"). A semaphore is a generalization of a lock (or, the other way around, a lock is a special case of a semaphore). Usually, but not necessarily, spinlocks are only valid within one process whereas semaphores can be used to synchronize between different processes, too.

一个锁适用于互斥,即有一个线程每次可以获取锁和code的一个关键部分进行。通常,这意味着code的修改由多个线程共享一些数据。结果
A 信号灯的有一个计数器,并让自己受到的一个或几个取决于什么线程,这取决于你发布什么价值给它,(在某些实现)收购了最大允许值。

A lock works for mutual exclusion, that is one thread at a time can acquire the lock and proceed with a "critical section" of code. Usually, this means code that modifies some data shared by several threads.
A semaphore has a counter and will allow itself being acquired by one or several threads, depending on what value you post to it, and (in some implementations) depending on what its maximum allowable value is.

只要,可以考虑一个锁定信号量的一种特殊情况为1的最大值。

Insofar, one can consider a lock a special case of a semaphore with a maximum value of 1.

2。他们做什么结果
如上所述,一个螺旋锁是锁定的,因此一个互斥(严格1至1)的机制。它的工作原理是反复查询和/或修改的存储器位置,通常以原子方式。这意味着,获得一个自旋锁是一个忙的操作,可能燃烧的CPU周期很长一段时间(也许永远!),而它有效地实现无。结果
对于这种方法的主要动机是,上下文切换有一个开销相当于纺几百(或者万)倍的事实,因此,如果锁可以通过燃烧几个周期旋转被收购,这可能整体非常不失为更高效。另外,对于实时应用来说可能是不可接受的,以阻止和等待调度回来它们在一些在未来远时间

2. What they do
As stated above, a spinlock is a lock, and therefore a mutual exclusion (strictly 1 to 1) mechanism. It works by repeatedly querying and/or modifying a memory location, usually in an atomic manner. This means that acquiring a spinlock is a "busy" operation that possibly burns CPU cycles for a long time (maybe forever!) while it effectively achieves "nothing".
The main incentive for such an approach is the fact that a context switch has an overhead equivalent to spinning a few hundred (or maybe thousand) times, so if a lock can be acquired by burning a few cycles spinning, this may overall very well be more efficient. Also, for realtime applications it may not be acceptable to block and wait for the scheduler to come back to them at some far away time in the future.

一个信号,相比之下,要么不旋转在所有的,或只旋转了很短的时间内(如一个优化,以避免系统调用的开销)。如果信号不能被收购,它阻止,CPU时间让给了一个不同的线程准备运行。当然,这可能意味着几毫秒内通过你的线程重新安排前,但如果这是没有问题的(通常不是),那么它可以是一个非常有效的,CPU-保守的做法。

A semaphore, by contrast, either does not spin at all, or only spins for a very short time (as an optimization to avoid the syscall overhead). If a semaphore cannot be acquired, it blocks, giving up CPU time to a different thread that is ready to run. This may of course mean that a few milliseconds pass before your thread is scheduled again, but if this is no problem (usually it isn't) then it can be a very efficient, CPU-conservative approach.

3。他们在拥挤的presence的行为结果
这是一个普遍的误解,认为自旋锁或无锁的算法是普遍较快,或者说,他们只负责很短的任务有用(理想情况下,没有同步对象应当保持比绝对必要的时间,永远)。

一个重要的区别是不同的方法如何表现的在拥塞presence

一个设计良好的系统通常有低或无拥塞(这意味着并不是所有的线程试图获得在准确的同一时间锁定)。例如,一个通常的的写code,其获取的锁,然后加载一半来自网络的zip-COM pressed兆字节的数据,德codeS和解析数据,最后修改释放锁之前的共享参考(数据追加到一个容器,等等)。相反,人们将获得锁只用于访问的共享资源的目的。结果
因为这意味着有比它里面的临界部以外相当多的工作,自然一个线程被临界区内部的可能性相对较低,并且因此很少线程竞争同时锁定。当然,每一个现在,然后两个线程试图获得在同一时间锁定(如果这的无法的发生,你不会需要一个锁!),但是这是非常例外的比排除在健康的制度。

A well-designed system normally has low or no congestion (this means not all threads try to acquire the lock at the exact same time). For example, one would normally not write code that acquires a lock, then loads half a megabyte of zip-compressed data from the network, decodes and parses the data, and finally modifies a shared reference (append data to a container, etc.) before releasing the lock. Instead, one would acquire the lock only for the purpose of accessing the shared resource.
Since this means that there is considerably more work outside the critical section than inside it, naturally the likelihood for a thread being inside the critical section is relatively low, and thus few threads are contending for the lock at the same time. Of course every now and then two threads will try to acquire the lock at the same time (if this couldn't happen you wouldn't need a lock!), but this is rather the exception than the rule in a "healthy" system.

在这种情况下,一个螺旋锁的大大的优于一个信号,因为如果没有锁定拥塞,获取自旋锁的开销是一个单纯的打循环相比数百/数千周期为一个作为上下文切换或10-20万次输球的一个时间段的剩余部分。

In such a case, a spinlock greatly outperforms a semaphore because if there is no lock congestion, the overhead of acquiring the spinlock is a mere dozen cycles as compared to hundreds/thousands of cycles for a context switch or 10-20 million cycles for losing the remainder of a time slice.

在另一方面,给予了高度充血,或者锁被关押时间较长(有时你就不能帮助它!),自旋锁将会燃烧四大皆空疯狂数量的CPU周期。结果
信号量(或互斥)在这种情况下一个更好的选择,因为它允许不同的线程来运行的有用的在这段时间的任务。或者,如果没有其他线程有事情做有用的,它可以让操作系统要减速的CPU并降低热量/节约能源。

On the other hand, given high congestion, or if the lock is being held for lengthy periods (sometimes you just can't help it!), a spinlock will burn insane amounts of CPU cycles for achieving nothing.
A semaphore (or mutex) is a much better choice in this case, as it allows a different thread to run useful tasks during that time. Or, if no other thread has something useful to do, it allows the operating system to throttle down the CPU and reduce heat / conserve energy.

此外,单核系统上,一个螺旋锁将处于锁定拥塞的presence相当低效的,作为纺丝线程将浪费其完整的时间等待的状态更改,不可能发生(直到释放线程被调度,其中的没有发生的等待线程运行时!)。因此,考虑的任何的争量,获取锁需要大约1 1/2时间片在最好的情况下(假设释放线程是被调度下一个),这不是很好的行为。

Also, on a single-core system, a spinlock will be quite inefficient in presence of lock congestion, as a spinning thread will waste its complete time waiting for a state change that cannot possibly happen (not until the releasing thread is scheduled, which isn't happening while the waiting thread is running!). Therefore, given any amount of contention, acquiring the lock takes around 1 1/2 time slices in the best case (assuming the releasing thread is the next one being scheduled), which is not very good behaviour.

4。他们是如何实施结果
信号量将时下一般包装 sys_futex Linux下(可以选择尝试几次后退出的自旋锁)。结果
自旋锁是用原子操作,并且不使用由操作系统提供的任何通常实现。在过去,这意味着使用任一编译器内在函数或非便携式汇编指令。同时这两个C ++ 11和C11具有原子操作作为语言的一部分,从写正确可证明无锁code的普通难度因此除了,现在可以实现在无锁code完全便携和(几乎)无痛的方式。

4. How they're implemented
A semaphore will nowadays typically wrap sys_futex under Linux (optionally with a spinlock that exits after a few attempts).
A spinlock is typically implemented using atomic operations, and without using anything provided by the operating system. In the past, this meant using either compiler intrinsics or non-portable assembler instructions. Meanwhile both C++11 and C11 have atomic operations as part of the language, so apart from the general difficulty of writing provably correct lock-free code, it is now possible to implement lock-free code in an entirely portable and (almost) painless way.

这篇关于自旋锁与信号量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆