How to make a multiple-read/single-write lock from more basic synchronization primitives?

sbi

We have found that we have several spots in our code where concurrent reads of data protected by a mutex are rather common, while writes are rare. Our measurements seem to say that using a simple mutex seriously hinders the performance of the code reading that data. So what we would need is a multiple-read/single-write mutex. I know that this can be built atop of simpler primitives, but before I try myself at this, I'd rather ask for existing knowledge:

What is an approved way to build a multiple-read/single-write lock out of simpler synchronization primitives?

I do have an idea how to make it, but I'd rather have answers unbiased by what I (probably wrongly) came up with. (Note: What I expect is an explanation how to do it, probably in pseudo code, not a full-fledged implementation. I can certainly write the code myself.)

Caveats:

  • This needs to have reasonable performance. (What I have in mind would require two lock/unlock operations per access. Now that might not be good enough, but needing many of them instead seems unreasonable.)

  • Commonly, reads are more numerous, but writes are more important and performance-sensitive than reads. Readers must not starve writers.

  • We are stuck on a rather old embedded platform (proprietary variant of VxWorks 5.5), with a rather old compiler (GCC 4.1.2), and boost 1.52 – except for most of boost's parts relying on POSIX, because POSIX isn't fully implemented on that platform. The locking primitives available basically are several kind of semaphores (binary, counting etc.), on top of which we have already created mutexes, conditions variables, and monitors.

  • This is IA32, single-core.

qqibrow

It seems like you only have mutex and condition_variable as synchronization primitives. therefore, I write a reader-writer lock here, which starves readers. it uses one mutex, two conditional_variable and three integer.

readers - readers in the cv readerQ plus the reading reader
writers - writers in cv writerQ plus the writing writer
active_writers - the writer currently writing. can only be 1 or 0.

It starve readers in this way. If there are several writers want to write, readers will never get the chance to read until all writers finish writing. This is because later readers need to check writers variable. At the same time, the active_writers variable will guarantee that only one writer could write at a time.

class RWLock {
public:
    RWLock()
    : shared()
    , readerQ(), writerQ()
    , active_readers(0), waiting_writers(0), active_writers(0)
    {}

    void ReadLock() {
        std::unique_lock<std::mutex> lk(shared);
        while( waiting_writers != 0 )
            readerQ.wait(lk);
        ++active_readers;
        lk.unlock();
    }

    void ReadUnlock() {
        std::unique_lock<std::mutex> lk(shared);
        --active_readers;
        lk.unlock();
        writerQ.notify_one();
    }

    void WriteLock() {
        std::unique_lock<std::mutex> lk(shared);
        ++waiting_writers;
        while( active_readers != 0 || active_writers != 0 )
            writerQ.wait(lk);
        ++active_writers;
        lk.unlock();
    }

    void WriteUnlock() {
        std::unique_lock<std::mutex> lk(shared);
        --waiting_writers;
        --active_writers;
        if(waiting_writers > 0)
            writerQ.notify_one();
        else
            readerQ.notify_all();
        lk.unlock();
    }

private:
    std::mutex              shared;
    std::condition_variable readerQ;
    std::condition_variable writerQ;
    int                     active_readers;
    int                     waiting_writers;
    int                     active_writers;
};

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

How to make the basic inverted index program more pythonic

From Dev

Can multiple threads/processes read/write from/to non-overlapping regions of a file simultaneously without synchronization?

From Dev

How to make a dictionary of synchronization objects?

From Dev

How to make a dictionary of synchronization objects?

From Dev

Is there any way to make this database lock more efficient?

From Dev

How to write a script to perform some basic operations on multiple csv files

From Dev

How do I make a Caps Lock from a Seach Button?

From Dev

How to write this more succinctly?

From Dev

How to write this more succinctly?

From Dev

How to write multiple files from a dictionary in python

From Dev

How to read/write to tempfile from multiple threads

From Dev

How to read from and write to multiple subfolders?

From Dev

C# - How to lock a method from being accessed by multiple process

From Dev

How to make multiple threads use the same socket to read and write?

From Dev

Make basic cipher function more readable

From Dev

How implementation of Re-entrant lock and Synchronization is different

From Dev

How to make a synchronization mutex with access by every process?

From Dev

How to make most stupid synchronization ever?

From Dev

How to make a synchronization mutex with access by every process?

From Dev

How to make more dices?

From Dev

How To Make More Functional?

From Dev

How to make it more beautiful?

From Dev

Java Multihreading Synchronization with Lock

From Dev

Conditional synchronization, lock

From Dev

How to make a single Array from multiple arrays

From Dev

Write-lock entity in Spring from database

From Dev

How do I make ABCPdf to automatically write to a new page when text requires more than 1 page?

From Dev

How to make php script to take information from javascript and the write it in mysql

From Dev

Java how to make JTextArea Accesible from different class and write in integer

Related Related

  1. 1

    How to make the basic inverted index program more pythonic

  2. 2

    Can multiple threads/processes read/write from/to non-overlapping regions of a file simultaneously without synchronization?

  3. 3

    How to make a dictionary of synchronization objects?

  4. 4

    How to make a dictionary of synchronization objects?

  5. 5

    Is there any way to make this database lock more efficient?

  6. 6

    How to write a script to perform some basic operations on multiple csv files

  7. 7

    How do I make a Caps Lock from a Seach Button?

  8. 8

    How to write this more succinctly?

  9. 9

    How to write this more succinctly?

  10. 10

    How to write multiple files from a dictionary in python

  11. 11

    How to read/write to tempfile from multiple threads

  12. 12

    How to read from and write to multiple subfolders?

  13. 13

    C# - How to lock a method from being accessed by multiple process

  14. 14

    How to make multiple threads use the same socket to read and write?

  15. 15

    Make basic cipher function more readable

  16. 16

    How implementation of Re-entrant lock and Synchronization is different

  17. 17

    How to make a synchronization mutex with access by every process?

  18. 18

    How to make most stupid synchronization ever?

  19. 19

    How to make a synchronization mutex with access by every process?

  20. 20

    How to make more dices?

  21. 21

    How To Make More Functional?

  22. 22

    How to make it more beautiful?

  23. 23

    Java Multihreading Synchronization with Lock

  24. 24

    Conditional synchronization, lock

  25. 25

    How to make a single Array from multiple arrays

  26. 26

    Write-lock entity in Spring from database

  27. 27

    How do I make ABCPdf to automatically write to a new page when text requires more than 1 page?

  28. 28

    How to make php script to take information from javascript and the write it in mysql

  29. 29

    Java how to make JTextArea Accesible from different class and write in integer

HotTag

Archive