开发者

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.

What I want:

pth开发者_Python百科read_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.

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.). 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?


The boost shared_mutex class supports reader (shared) and writer (unique) locks and temporary upgrades from shared to unique locks.

Example for boost shared_mutex (multiple reads/one write)?

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. That means it's also supported on windows ;) Have a look: Pthreads-w32.

Additionally, consider using OpenMP instead of locks: the compiler extension provides portable critical sections, kernes threading model, tasks and much more! MS C++ supports this technology as well as g++ in Linux.

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;
    };
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜