简体   繁体   English

如何使用“upgrade_to_unique_lock”执行“try_lock”

[英]How to do a “try_lock” with an “upgrade_to_unique_lock”

I want to perform an upgrade_to_unique_lock on an upgrade_lock without blocking but a cursory look at the Boost source code (v1.46.1) shows that this is impossible? 我想在upgrade_lock上执行upgrade_to_unique_lock而不会阻塞,但粗略地看一下Boost源代码(v1.46.1)表明这是不可能的? Is my approach wrong? 我的方法有误吗?

I want to first obtain a read lock on a resource that can also potentially be held for reading by other threads. 我想首先获得资源上的读锁定,该读取锁定也可能被其他线程读取。 Then I want to see if it is available for writing and if not (other shared read locks are currently held on it) simply do it later. 然后我想看看它是否可用于写入,如果没有(其他共享读锁当前保持在它上面),只需稍后再做。

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

I'm trying to procedurally generate terrain tiles (pages) seamlessly using the midpoint displacement algorithm asynchronously. 我正在尝试以异步方式使用中点位移算法无缝地生成地形图块(页面)。 This requires seeding the subject terrain tile (center) with edges obtained from the 4 surrounding tiles (north, west, east, south). 这需要使用从4个周围的瓦片(北,西,东,南)获得的边缘来播种对象地形瓦片(中心)。 Edges are collected only from neighbors that exist and are fully generated already. 边缘仅从存在且已完全生成的邻居收集。 The implementation should block on one neighbor tile at a time and not hold read locks of other neighbors freeing them-up to be generated at any time. 该实现应该一次阻塞一个邻居区块,并且不保持其他邻居的读锁定,从而释放它们随时生成。 When a tile is being generated, it must guarantee that no other threads have write locks to its neighbors, read locks are ok. 在生成tile时,它必须保证没有其他线程对其邻居有写锁,读锁是可以的。 Also, there should not be a daisy-chain of threads waiting on write-locks needlessly (ie tiles two tiles apart in distance should be able to generate independently of each other). 此外,不应该有一个菊花链的线程在不必要地等待写锁(即,距离上的两个瓦片应该能够彼此独立地生成)。

My implementation depends on a third-party algorithm that requests pages asynchronously as needed based on viewing distance from a camera. 我的实现依赖于第三方算法,该算法根据查看相机的距离,根据需要异步请求页面。 It looks like it can arbitrarily make up to 16 asynchronous requests for pages / tiles in no particular order. 看起来它可以在没有特定顺序的情况下任意地为页面/图块组成16个异步请求。

Straw man answer. 稻草人回答。 I'm pretty sure this isn't a valid answer. 我很确定这不是一个有效的答案。 But I can't put it in a comment because of formatting concerns. 但由于格式问题,我无法将其置于评论中。

To generate the center tile I would be tempted to do something like this: 为了生成中心区块,我很想做这样的事情:

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
    // ...
}

This is using C++11 bits like std::unique_lock and std::defer_lock . 这是使用C ++ 11位,如std::unique_lockstd::defer_lock I believe you can get this functionality from boost too (not positive though). 我相信你也可以从boost获得这个功能(虽然不是正面的)。

This routine atomically exclusively locks the center, and share-locks the neighbors. 该例程以原子方式独占锁定中心,并共享锁定邻居。 It blocks until it can get all of the locks. 它会阻塞,直到它可以获得所有锁定。 It doesn't prevent its neighbors from doing the same thing. 它并不妨碍其邻居做同样的事情。 That is, use of std::lock will ensure there is no deadlock. 也就是说,使用std::lock将确保没有死锁。

I'm very much unsure that this is actually addressing what you're trying to do. 我非常不确定这实际上是在解决你想要做的事情。 But perhaps it will help lead to an answer... 但也许它会有助于找到答案......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM