2009-01-17 38 views
4

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

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

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

回答

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 

由于其他线程不断测试锁,直到他们让进了关键的部分,这是保证相互排斥的一种非常低效的方式。然而,使用这个简单的概念,您可以构建更复杂的控制结构,如效率更高的信号量(因为进程不循环,它们正在睡眠)

10

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

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

+0

谢谢我试图找出函数是否有每个线程的单独实例。但是,你能提供一个链接给你从这个信息来源吗? – 2009-01-17 06:04:58

+0

我没有函数变量的来源,对不起。但愿我做了,可惜我没有。其余部分来自信号量维基百科文章。 – Sydius 2009-01-17 06:32:16

4

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

函数中的普通局部变量已经专用于单个线程。只有静态,全局或其他数据可以被多个线程同时访问,而这些线程需要使用锁来保护它。

0

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

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