您将如何在C ++ 11中实现自己的读取器/写入器锁?

我有一组需要使用读取器/写入器锁保护的数据结构。我知道boost :: shared_lock,但是我想使用std :: mutex,std :: condition_variable和/或std :: atomic进行自定义实现,以便我更好地了解它的工作原理(并在以后进行调整) 。


每个数据结构(可移动但不可复制)都将从称为Commons的类继承,该类封装了锁定。我希望公共界面看起来像这样:


class Commons {

public:

    void read_lock();

    bool try_read_lock();

    void read_unlock();


    void write_lock();

    bool try_write_lock();

    void write_unlock();

};

...以便可以被某些人公开继承:


class DataStructure : public Commons {};

我正在编写科学代码,通常可以避免数据争用;这个锁主要是为了防止我以后可能犯的错误。因此,我的优先事项是低读取开销,因此我不会过多地妨碍正确运行的程序。每个线程可能将在其自己的CPU内核上运行。


您能给我看一下(密码可以吗)读/写锁?我现在所拥有的应该是防止作家饥饿的变体。到目前为止,我的主要问题一直是read_lock之间的差距,即检查读取是否可以安全地实际增加读者数量,然后write_lock知道要等待。


void Commons::write_lock() {

    write_mutex.lock();

    reading_mode.store(false);

    while(readers.load() > 0) {}

}


void Commons::try_read_lock() {

    if(reading_mode.load()) {

        //if another thread calls write_lock here, bad things can happen

        ++readers; 

        return true;

    } else return false;

}

我是多线程的新手,我真的很想了解它。在此先感谢您的帮助!


大话西游666
浏览 286回答 3
3回答

收到一只叮咚

//// Multi-reader Single-writer concurrency base class for Win32//// (c) 1999-2003 by Glenn Slayden (glenn@glennslayden.com)////#include "windows.h"class MultiReaderSingleWriter{private:    CRITICAL_SECTION m_csWrite;    CRITICAL_SECTION m_csReaderCount;    long m_cReaders;    HANDLE m_hevReadersCleared;public:    MultiReaderSingleWriter()    {        m_cReaders = 0;        InitializeCriticalSection(&m_csWrite);        InitializeCriticalSection(&m_csReaderCount);        m_hevReadersCleared = CreateEvent(NULL,TRUE,TRUE,NULL);    }    ~MultiReaderSingleWriter()    {        WaitForSingleObject(m_hevReadersCleared,INFINITE);        CloseHandle(m_hevReadersCleared);        DeleteCriticalSection(&m_csWrite);        DeleteCriticalSection(&m_csReaderCount);    }    void EnterReader(void)    {        EnterCriticalSection(&m_csWrite);        EnterCriticalSection(&m_csReaderCount);        if (++m_cReaders == 1)            ResetEvent(m_hevReadersCleared);        LeaveCriticalSection(&m_csReaderCount);        LeaveCriticalSection(&m_csWrite);    }    void LeaveReader(void)    {        EnterCriticalSection(&m_csReaderCount);        if (--m_cReaders == 0)            SetEvent(m_hevReadersCleared);        LeaveCriticalSection(&m_csReaderCount);    }    void EnterWriter(void)    {        EnterCriticalSection(&m_csWrite);        WaitForSingleObject(m_hevReadersCleared,INFINITE);    }    void LeaveWriter(void)    {        LeaveCriticalSection(&m_csWrite);    }};我没有机会尝试,但是代码看起来还可以。

犯罪嫌疑人X

您可以按照此处(我写的)确切的Wikipedia算法实现Readers-Writers锁定:#include <iostream>#include <thread>#include <mutex>#include <condition_variable>int g_sharedData = 0;int g_readersWaiting = 0;std::mutex mu;bool g_writerWaiting = false;std::condition_variable cond;void reader(int i){&nbsp; &nbsp; std::unique_lock<std::mutex> lg{mu};&nbsp; &nbsp; while(g_writerWaiting)&nbsp; &nbsp; &nbsp; &nbsp; cond.wait(lg);&nbsp; &nbsp; ++g_readersWaiting;&nbsp; &nbsp; // reading&nbsp; &nbsp; std::cout << "\n reader #" << i << " is reading data = " << g_sharedData << '\n';&nbsp; &nbsp; // end reading&nbsp; &nbsp; --g_readersWaiting;&nbsp; &nbsp; while(g_readersWaiting > 0)&nbsp; &nbsp; &nbsp; &nbsp; cond.wait(lg);&nbsp; &nbsp; cond.notify_one();}void writer(int i){&nbsp; &nbsp; std::unique_lock<std::mutex> lg{mu};&nbsp; &nbsp; while(g_writerWaiting)&nbsp; &nbsp; &nbsp; &nbsp; cond.wait(lg);&nbsp; &nbsp; // writing&nbsp; &nbsp; std::cout << "\n writer #" << i << " is writing\n";&nbsp; &nbsp; g_sharedData += i * 10;&nbsp; &nbsp; // end writing&nbsp; &nbsp; g_writerWaiting = true;&nbsp; &nbsp; while(g_readersWaiting > 0)&nbsp; &nbsp; &nbsp; &nbsp; cond.wait(lg);&nbsp; &nbsp; g_writerWaiting = false;&nbsp; &nbsp; cond.notify_all();}//lg.unlock()int main(){&nbsp; &nbsp; std::thread reader1{reader, 1};&nbsp; &nbsp; std::thread reader2{reader, 2};&nbsp; &nbsp; std::thread reader3{reader, 3};&nbsp; &nbsp; std::thread reader4{reader, 4};&nbsp; &nbsp; std::thread writer1{writer, 1};&nbsp; &nbsp; std::thread writer2{writer, 2};&nbsp; &nbsp; std::thread writer3{writer, 3};&nbsp; &nbsp; std::thread writer4{reader, 4};&nbsp; &nbsp; reader1.join();&nbsp; &nbsp; reader2.join();&nbsp;&nbsp; &nbsp; reader3.join();&nbsp; &nbsp; reader4.join();&nbsp; &nbsp; writer1.join();&nbsp; &nbsp; writer2.join();&nbsp; &nbsp; writer3.join();&nbsp; &nbsp; writer4.join();&nbsp; &nbsp; return(0);}
打开App,查看更多内容
随时随地看视频慕课网APP