2

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(); 
  } 
}

定时锁定

问题> 我在理解以下几行时遇到问题:

  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; 

这个想法正确吗?我认为代码的目的是确保在对象有锁的情况下执行上述行。但根据我的理解(我猜是不正确的),上面的行总是会运行!

问题出在哪里?

4

2 回答 2

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将“持续”尝试获取锁,但如果指定时间已过则放弃。

于 2013-01-07T17:19:38.380 回答
1

You are right. The example doesn't properly handle the state of when the mutex fails to lock. If you read closely just below that example you'll see this quoted there:

The above example uses various methods to illustrate some of the features provided by boost::unique_lock. Certainly, the usage of these features does not necessarily make sense for the given scenario; the usage of boost::lock_guard in the previous example was already adequate. This example is rather meant to demonstrate the possibilities offered by boost::unique_lock.

于 2013-01-07T17:08:22.153 回答