boost :: unique_lock :: timed_lock的用法

时间:2013-01-07 16:47:47

标签: c++ boost

boost::timed_lock

void wait(int seconds) 
{ 
  boost::this_thread::sleep(boost::posix_time::seconds(seconds)); 
} 

boost::timed_mutex mutex; 

void thread() 
{ 
  for (int i = 0; i < 5; ++i) 
  { 
    wait(1); 
    boost::unique_lock<boost::timed_mutex> lock(mutex, boost::try_to_lock); 
    if (!lock.owns_lock()) 
      lock.timed_lock(boost::get_system_time() + boost::posix_time::seconds(1));//<<<<
    std::cout << "Thread " << boost::this_thread::get_id() << ": " << i << std::endl; 
    boost::timed_mutex *m = lock.release(); 
    m->unlock(); 
  } 
}

timed_lock

问题&GT;我有问题要理解以下几行:

  if (!lock.owns_lock()) 
     lock.timed_lock(boost::get_system_time() + 
                     boost::posix_time::seconds(1));//<<<<

这是我的理解。假设lock.owns_lock()返回false,这意味着当前对象不拥有可锁定对象的锁。所以下一行将被执行。如果在指定的时间过去后对象仍然无法获得锁定,那么boost::timed_lock将返回false。那么下面的行将被执行???

std::cout << "Thread " << boost::this_thread::get_id() << ": " << i << std::endl; 

这个想法是否正确?我认为代码的目的是确保如果对象具有锁定,则执行上面的行。但根据我的理解(我猜不正确),上面的行总是运行!

问题出在哪里?

2 个答案:

答案 0 :(得分:3)

您是对的,该示例并不保证在执行受保护的代码之前始终正确获取锁。

鉴于以下示例的解释:

  

上面的程序将boost :: try_to_lock作为第二个参数传递给boost :: unique_lock的构造函数。可以通过owns_lock()方法检查是否已获取互斥锁。如果它没有 - owns_lock()返回false - 使用boost :: unique_lock提供的另一个函数:timed_lock()等待一定时间来获取互斥锁。给定的程序等待一秒钟,这应该是获取互斥锁的足够时间。

     

该示例实际上显示了获取互斥锁的三种基本方法:lock()等待直到获取互斥锁。 try_lock()不会等待,但如果在调用时可用,则获取互斥锁,否则返回false。最后,timed_lock()尝试在给定的时间段内获取互斥锁。与try_lock()一样,成功或失败由bool类型的返回值表示。

作者似乎意识到了这个问题(假设该文件是timed_lock的返回值)但是没有想到重新测试是否需要获得锁定(正如他们所说的那样“等待最多一秒,这应该是获得互斥量的足够时间“)。


您理解中的一个错误:

  

如果在指定的时间过后且对象仍无法获得锁定,则boost :: timed_lock将返回false。

事实并非如此。 timed_lock将“不断”尝试获取锁定,但如果指定的时间已过期则放弃。

答案 1 :(得分:1)

你是对的。该示例无法正确处理互斥锁无法锁定的状态。如果您仔细阅读该示例下方的内容,您会在那里看到:

  

上面的示例使用各种方法来说明boost :: unique_lock提供的一些功能。当然,这些功能的使用对于给定的场景不一定有意义;在前面的例子中使用boost :: lock_guard已经足够了。这个例子的目的是为了演示boost :: unique_lock提供的可能性。