0

我想在没有阻塞的情况下对 upgrade_lock 执行 upgrade_to_unique_lock 但粗略查看 Boost 源代码 (v1.46.1) 表明这是不可能的?我的方法错了吗?

我想首先获得一个资源的读锁,该资源也可能被其他线程持有以供读取。然后我想看看它是否可用于写入,如果没有(其他共享读锁当前持有),稍后再做。

// No way to specify the boost::try_to_lock object
explicit upgrade_to_unique_lock(upgrade_lock<Mutex>& m_):
    source(&m_),exclusive(move(*source))

我正在尝试异步使用中点位移算法在程序上无缝地生成地形图块(页面)。这需要使用从周围 4 个瓷砖(北、西、东、南)获得的边缘来播种主题地形图块(中心)。边缘仅从存在且已完全生成的邻居中收集。实现应该一次阻塞一个邻居块,而不是持有其他邻居的读锁,以便随时生成释放它们。生成瓦片时,它必须保证没有其他线程对其邻居有写锁,读锁是可以的。此外,不应该有一个菊花链的线程不必要地等待写锁(即距离相隔两个瓷砖的瓷砖应该能够相互独立地生成)。

我的实现依赖于第三方算法,该算法根据与相机的观看距离根据需要异步请求页面。看起来它可以任意地对页面/图块进行多达 16 个异步请求,没有特定的顺序。

4

1 回答 1

2

稻草人回答。我很确定这不是一个有效的答案。但由于格式问题,我无法将其放在评论中。

要生成中心图块,我很想做这样的事情:

tile::generate_center()
{
    tile& north = ...;
    tile& east = ...;
    tile& south = ...;
    tile& west = ...;
    std::unique_lock<mutex_type> l0(mutex(), std::defer_lock);
    shared_lock<mutex_type> ln(north.mutex(), std::defer_lock);
    shared_lock<mutex_type> le(east.mutex(), std::defer_lock);
    shared_lock<mutex_type> ls(south.mutex(), std::defer_lock);
    shared_lock<mutex_type> lw(west.mutex(), std::defer_lock);
    std::lock(l0, ln, le, ls, lw);
    // This is exclusively locked, neighbors are share locked
    // ...
}

这是使用 C++11 位,例如std::unique_lockand std::defer_lock。我相信你也可以从 boost 中获得这个功能(虽然不是积极的)。

该例程以原子方式独占锁定中心,并共享锁定邻居。它阻塞,直到它可以得到所有的锁。它不会阻止它的邻居做同样的事情。也就是说,使用 ofstd::lock将确保没有死锁。

我非常不确定这实际上是在解决您正在尝试做的事情。但也许它会帮助你找到答案......

于 2011-07-28T00:52:33.120 回答