我对锁和互斥锁之间的区别感到非常困惑。在Boost文档中,它说,
锁定类型
互斥锁类型
在另一篇文章中,我看到了这样的函数,
boost::shared_mutex _access;
void reader()
{
boost::shared_lock< boost::shared_mutex > lock(_access);
// do work here, without anyone having exclusive access
}
void conditional_writer()
{
boost::upgrade_lock< boost::shared_mutex > lock(_access);
// do work here, without anyone having exclusive access
if (something) {
boost::upgrade_to_unique_lock< boost::shared_mutex > uniqueLock(lock);
// do work here, but now you have exclusive access
}
// do more work here, without anyone having exclusive access
}
更新了问题
答案 0 :(得分:37)
互斥锁是同步对象。您在代码段的开头获取互斥锁,并在最后释放它,以确保没有其他线程同时访问相同的数据。互斥锁通常具有与其保护的数据相同的生命周期,并且多个线程可以访问一个互斥锁。
锁定对象是封装该锁的对象。构造对象时,它获取互斥锁上的锁。当它被破坏时,锁被释放。您通常会为每次访问共享数据创建一个新的锁定对象。
答案 1 :(得分:11)
互斥锁是可以锁定的对象。锁是对象 保持锁定。要创建锁,您需要将其传递给互斥锁。
答案 2 :(得分:1)
锁定可以提供互斥而不是条件同步。与信号量不同,锁具有所有者,所有权起着重要作用 锁定行为中的角色
示例 -
class lockableObject { public void F() {
mutex.lock(); ...; mutex.unlock();
}
public void G() {
mutex.lock(); ...; F(); ...; mutex.unlock();
}
private mutexLock mutex; }
// method G() calls method F()
类lockableObject中的锁定互斥锁用于将方法F()和G()转换为关键部分。因此,一次只能有一个线程在lockableObject的方法内执行。当线程调用方法G()时,互斥锁被锁定。当方法G()调用方法F()时,mutex.lock()在F()中执行,但调用线程没有被阻塞,因为它已经拥有了互斥锁。如果互斥锁是二进制信号量而不是锁,则在F()中执行mutex.P()时,从G()到F()的调用将阻塞调用线程。 (回想一下,对二进制信号量的P()和V()操作的补充必须交替。)这会产生死锁,因为没有其他线程能够在F()或G()内执行。
这些是锁和二进制信号量之间的差异: 1对于二进制信号量,如果对P()进行两次调用而没有对V()的任何干预,则第二次调用将阻塞。但是,拥有锁并再次请求所有权的线程不会被阻止。 (请注意锁定并不总是递归的,因此在使用锁之前请检查文档。) 2连续调用lock()和unlock()的所有者必须是同一个线程。但是对P()和V()的连续调用可以由不同的线程进行。