锁(线程)原子?

时间:2010-02-06 17:13:35

标签: multithreading locking atomic

这听起来像是一个愚蠢的问题,但是如果在多线程应用程序中锁定资源,那么资源上发生的操作是原子地完成的吗?

I.E。:当资源锁定时,处理器是否可以中断或者是否可以进行上下文切换?如果确实如此,那么在重新安排它的过程之前,没有其他任何东西可以访问该资源。听起来很昂贵。

4 个答案:

答案 0 :(得分:16)

处理器肯定可以切换到另一个线程,是的。实际上,在大多数现代计算机中,无论​​如何都可以有多个线程同时运行。锁定只是确保没有其他线程可以获取相同的锁,因此您可以确保该资源上的操作在该资源方面是原子。使用其他资源的代码可以完全独立运行。

您应该尽可能锁定短期操作。您还可以选择锁的粒度...例如,如果共享对象中有两个独立变量,则可以使用两个单独的锁来保护对这些变量的访问。这可能会提供更好的并发性 - 但与此同时,更多的锁意味着更多的复杂性和更多的死锁可能性。在并发方面,总会有一种平衡的行为。

答案 1 :(得分:7)

你说得对。这就是为什么在短时间内锁定如此重要的一个原因。但是,这并不像它听起来那么糟糕,因为没有其他正在等待锁的线程将被调度,直到持有锁的线程释放它。

答案 2 :(得分:2)

是的,肯定会发生上下文切换。 这正是为什么在访问共享资源时,将其从另一个线程锁定也很重要。当线程A具有锁定时,线程B无法访问锁定的代码。

例如,如果两个线程运行以下代码:

1. lock(l);
2. -- change shared resource S here --
3. unlock(l);

在步骤1之后可以发生上下文切换,但是其他线程当时无法保持锁定,因此无法更改共享资源。如果在没有锁定的情况下访问其中一个线程上的共享资源 - 可能会发生不好的事情!

关于浪费,是的,这是一种浪费的方法。这就是为什么有些方法试图完全避免锁定。这些方法称为lock-free,其中一些方法基于强锁定服务,例如CAS(比较和交换)或其他方法。

答案 3 :(得分:0)

不,它并不贵。通常只有两种可能性:

1)系统还可以执行其他操作:在这种情况下,系统仍在对所有可用内核进行有用的工作。

2)系统没有其他任何操作:在这种情况下,将安排持有锁的线程。一个理智的系统不会留下未使用的核心,而有一个未经安排的可立即运行的线程。

那么,它怎么会贵?如果没有其他任何系统要做,那就不需要获取该锁(或者没有足够的其他东西来占用所有内核)并且持有锁的线程准备好运行。因此,您必须避免这种情况,并且上下文切换或抢占问题无关紧要(因为线程可以随时运行)。