简体   繁体   English

可升级读/写锁Win32

[英]Upgradeable read/write lock Win32

I am in search of an upgradeable read write lock for win32 with the behaviour of pthreads rwlock, where a read lock can be up- and downgraded.我正在寻找具有 pthreads rwlock 行为的 win32 可升级读写锁,其中可以升级和降级读取锁。

What I want:我想要的是:

pthread_rwlock_rdlock( &lock );
...read...
if( some condition ) {
    pthread_rwlock_wrlock( &lock );
    ...write...
    pthread_rwlock_unlock( &lock );
}
...read...
pthread_rwlock_unlock( &lock );

The upgrade behaviour is not required by posix, but it works on linux on mac. posix 不需要升级行为,但它适用于 mac 上的 linux。

Currently, I have a working implementation (based on an event, a semaphore and a critical section) that is upgradeable, but the upgrade may fail when readers are active.目前,我有一个可升级的工作实现(基于事件、信号量和临界区),但是当阅读器处于活动状态时升级可能会失败。 If it fails a read unlock + recheck + write lock is necessary.如果失败,则需要读取解锁 + 重新检查 + 写入锁定。

What I have:我有的:

lock.rdlock();
...read...
if( some condition ) {
    if( lock.tryupgrade() ) {
        ...write...
        lock.unlock();
        return;
    } else {
        lock.unlock();
        // <- here, other threads may alter the condition ->
        lock.wrlock();
        if( some condition ) { // so, re-check required
            ...write...
        }
        lock.unlock();
        return;
    }
}
...read...
lock.unlock();

EDIT: The bounty:编辑:赏金:

I am still in search, but want to add some restrictions: it is used intra-process-only (so based on critical sections is ok, WIN32 mutexes are not ok), and it should be pure WIN32 API (no MFC, ATL etc.).我还在搜索中,但想添加一些限制:它仅用于进程内(因此基于关键部分可以,WIN32互斥锁不行),它应该是纯WIN32 API(没有MFC,ATL等.)。 Acquiring read locks should be fast (so, acquiring the read lock should not enter a critical section in its fast path).获取读锁应该很快(因此,获取读锁不应该进入其快速路径中的临界区)。 Maybe an InterlockedIncrement based solution is possible?也许基于 InterlockedIncrement 的解决方案是可能的?

The boost shared_mutex class supports reader (shared) and writer (unique) locks and temporary upgrades from shared to unique locks. boost shared_mutex类支持读取器(共享)和写入器(唯一)锁,以及从共享锁到唯一锁的临时升级。

Example for boost shared_mutex (multiple reads/one write)? 用于boost shared_mutex的示例(多次读取/一次写入)?

I don't recommend writing your own, it's a tricky thing to get right and difficult to test thoroughly. 我不建议您自己编写,要正确正确地进行测试是一件棘手的事情。

pthread library is a 'Portable Threads' library. pthread库是一个“便携式线程”库。 That means it's also supported on windows ;) Have a look: Pthreads-w32 . 这意味着Windows上也支持它;)看一下: Pthreads-w32

Additionally, consider using OpenMP instead of locks: the compiler extension provides portable critical sections, kernes threading model, tasks and much more! 另外,考虑使用OpenMP代替锁:编译器扩展提供了可移植的关键部分,kernes线程模型,任务等等! MS C++ supports this technology as well as g++ in Linux. MS C ++以及Linux中的g ++都支持该技术。

Cheers! 干杯! :) :)

What is wrong with this approach?这种方法有什么问题?

    // suppose:
    struct RwLock
    {
        void AcquireExclusive();
        void AcquireShared();
        void Release();
        bool TryAcquireExclusive();
    };

    // rwlock that has TryAcquireSharedToExclusive
    struct ConvertableRwLock
    {
        void AcquireExclusive()
        {
            writeIntent.AcquireExclusive();
            rwlock.AcquireExclusive();
            writeIntent.Release();
        }

        void AcquireShared()
        { 
            readIntent.AcquireShared();
            rwlock.AcquireShared();
            readIntent.Release();
        }

        void Release()
        {
            rwlock.Release();
        }

        bool TryConvertSharedToExclusive()
        {
            // Defer to other exclusive including convert.
            // Avoids deadlock with other TryConvertSharedToExclusive.
            if (!writeIntent.TryAcquireExclusive())
            {
                rwlock.Release();
                return false;
            }

            // starve readers
            readIntent.AcquireExclusive();

            // release full lock, but no other can acquire since
            // this thread has readIntent and writeIntent.
            rwlock.Release();

            // Wait for other shared to drain.
            rwlock.AcquireExclusive();

            readIntent.Release();
            writeIntent.Release();
            return true;
        }

    private:
        RwLock rwlock;
        RwLock readIntent;
        RwLock writeIntent;
    };

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

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