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();
}
}
问题&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;
这个想法是否正确?我认为代码的目的是确保如果对象具有锁定,则执行上面的行。但根据我的理解(我猜不正确),上面的行总是运行!
问题出在哪里?
答案 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提供的可能性。