自旋锁和信号灯有什么区别?


15

自旋锁和动作信号灯之间的基本区别是什么?



@Gilles我也看过那个,但页面上唯一提及信号量的是沃伦评论道:“如果要知道自旋锁与信号量之间的区别,那就是另外一个问题。”
Michael Mrozek

@Michael:好的,我认为那里的答案解决了要点,但您说对了,没有人明确指出信号量是其他类型的锁之一。
吉尔斯(Gilles)“所以,别再作恶了”


stackoverflow.com/questions/195853/spinlock-versus-semaphore的副本我问的线程中存在许多很好的解释。
iankits

Answers:


13

两者都管理有限的资源。我将首先描述二进制信号量(互斥体)和自旋锁之间的区别。

自旋锁执行繁忙的等待-即,它保持运行循环:

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)

好的解释,我只想强调一点。信号量与互斥量是一个接口问题:一个互斥量是否保留,而一个信号量最多由N个线程保持;互斥锁是N = 1的信号量的特例。自旋锁与其他类型的锁是实现问题:自旋锁不断尝试获取该锁,而其他类型则等待通知。在Linux内核上下文中,唯一具有spin实现的锁具有互斥锁接口。
吉尔斯(Gilles)“所以,别再邪恶了”,2010年

在Linux内核上下文中,唯一具有spin实现的锁具有互斥锁接口。我不明白这条线。您能对此进行扩展吗?

@Sen:他的意思是Linux中的自旋锁表现为二进制(无论是否已锁定)。可能有一个旋转锁表现为信号量。
Maciej Piechotka 2011年

“但是,如果锁定线程被其他尝试访问同一资源的线程抢占,则第二个线程只是尝试释放资源,直到它耗尽CPU数量。”:但是Mutex仍然存在问题。如果具有更高优先级的任务需要访问资源该怎么办……它是否刚刚排队?最好使具有不同优先级的任务之间的资源共享无效。
Hibou57

@ Hibou57:是的,它被阻止了,因为状态不一致,并且使用资源会产生“有趣”的效果(例如,低优先级线程正在向链表添加或从链表中删除某些内容)。该语句的要点是,如果线程被阻塞,则不会对其进行调度,因此它不会在线程等待自旋锁时消耗资源。锁定实时系统(尤其是硬系统)是另外一个话题,我没有足够的知识来回答它-但是,这些系统有时会实施优先级捐赠或其他技术。
Maciej Piechotka

2

自旋锁用于不允许睡眠的中断环境中。它们以紧密的循环进行轮询,直到获取资源为止不执行其他操作。通常用于ISR,更加安全,高效。

信号量可用于可以正常睡眠的过程环境中。


1

这是我的快速答案:旋转锁和二进制信号量(管理只能由一件事使用的资源)几乎相同。它们的区别是自旋锁管理要运行的代码,而二进制信号量则管理某种形式的资源(例如cpu时间,显示输出)

但是,常规的信号量能够管理访问资源的多个线程,这些线程可以在多个线程之间进行分配,但是受到限制(例如,内存,网络带宽)

简而言之,自旋锁很可能会不断询问信号量是否可以使用资源。(想象一下一个孩子不得不上洗手间,等待别人洗完澡。)

资料来源:系统编程,操作系统和维基百科的简介

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.