自旋锁和信号量在操作上有哪些基本区别?
答案1
两者都管理有限的资源。我将首先描述二进制信号量(互斥锁)和自旋锁之间的区别。
自旋锁执行繁忙等待 - 即它继续运行循环:
while (try_acquire_resource ());
...
release();
它执行非常轻量级的锁定/解锁,但如果锁定线程将被其他尝试访问相同资源的线程抢占,则第二个线程将简单地尝试获取资源,直到耗尽 CPU 量子。
另一方面互斥体表现得更像:
if (!try_lock()) {
add_to_waiting_queue ();
wait();
}
...
process *p = get_next_process_from_waiting_queue ();
p->wakeUp ();
因此,如果线程尝试获取被阻止的资源,它将被挂起,直到它可用为止。锁定/解锁要繁重得多,但等待是“免费”且“公平”的。
信号是一个允许多次使用(从初始化得知)的锁 - 例如允许 3 个线程同时持有资源,但不能再多了。例如,它用于生产者/消费者问题或一般队列中:
P(resources_sem)
resource = resources.pop()
...
resources.push(resources)
V(resources_sem)
答案2
自旋锁用于不允许休眠的中断上下文中。它们在一个紧密的循环中进行轮询,在获取资源之前不执行任何其他操作。主要用于ISR,更加安全高效。
信号量可以在进程上下文中使用,其中睡眠是可以的。
答案3
这是我的快速回答:自旋锁和二进制信号量(管理只能由一个事物使用的资源)几乎相同。它们的区别在于,自旋锁管理要运行的代码,而二进制信号量管理某种单一资源(例如 CPU 时间、显示输出)
然而,常规信号量能够管理访问资源的多个线程,该资源可以分割为多个,但受到限制(例如内存、网络带宽)
简而言之,自旋锁可能会不断询问信号量是否可以使用资源。 (想象一下一个孩子必须使用卫生间并等待其他人完成。)
来源:系统编程简介、操作系统和维基百科