为什么锁有效?

时间:2009-01-17 05:21:48

标签: c++ multithreading boost locking mutex

如果锁确保一次只有一个线程访问锁定的数据,那么是什么控制对锁定函数的访问?

我认为boost::mutex::scoped_lock应该在我的每个函数的开头,所以局部变量不会被另一个线程意外修改,这是正确的吗?如果两个线程试图在非常接近的时间获取锁定怎么办?内部使用的锁的局部变量不会被另一个线程破坏吗?

我的问题不是特定于推特,但我可能会使用它,除非你推荐另一个。

4 个答案:

答案 0 :(得分:10)

您只需拥有对共享数据的独占访问权限。除非它们是静态的或在堆上,否则函数内的局部变量将针对不同的线程具有不同的实例,并且不必担心。但是应该首先锁定共享数据(例如通过指针访问的内容)。

至于锁是如何工作的,它们经过精心设计以防止竞争条件,并且通常具有硬件级支持以保证原子性。 IE,有一些机器语言结构保证是原子的。信号量(和互斥量)可以通过这些实现。

答案 1 :(得分:10)

你是对的,在实现锁时,你需要一些方法来保证两个进程不会同时获得锁。要做到这一点,你需要使用一个原子指令 - 一个保证完成而不会中断的指令。一个这样的指令是test-and-set,这个操作将获得布尔变量的状态,将其设置为true,并返回先前检索的状态。

这样做可以让你编写不断测试的代码,看看它是否可以获得锁定。假设x是线程之间的共享变量:

while(testandset(x));
// ...
// critical section
// this code can only be executed by once thread at a time
// ...
x = 0; // set x to 0, allow another process into critical section

由于其他线程不断测试锁定,直到它们进入临界区域,这是一种保证互斥的非常低效的方法。但是,使用这个简单的概念,您可以构建更复杂的控制结构,如信号量更高效(因为进程不循环,它们正在休眠)

答案 2 :(得分:4)

最简单的解释是,锁定在下面,基于硬件指令,该指令保证是原子的,并且不能在线程之间发生冲突。

函数中的普通局部变量已经特定于单个线程。它只是静态,全局或其他数据,可以由多个线程同时访问,需要有锁保护它。

答案 3 :(得分:0)

操作锁的机制控制对它的访问。

任何锁定原语都需要能够在处理器之间进行通信,因此通常在总线操作之上实现,即读取和写入内存。它还需要被构造成使得试图声明它的两个线程不会破坏其状态。这并不容易,但您通常可以相信任何操作系统实现的锁都不会被多个线程破坏。