为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C++
大话西游666 2019-11-27 10:15:31
我有一组需要使用读取器/写入器锁保护的数据结构。我知道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;}我是多线程的新手,我真的很想了解它。在此先感谢您的帮助!
查看完整描述

3 回答

?
收到一只叮咚

TA贡献1821条经验 获得超4个赞

//

// 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);

    }

};

我没有机会尝试,但是代码看起来还可以。


查看完整回答
反对 回复 2019-11-27
?
犯罪嫌疑人X

TA贡献2080条经验 获得超4个赞

您可以按照此处(我写的)确切的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)

{

    std::unique_lock<std::mutex> lg{mu};

    while(g_writerWaiting)

        cond.wait(lg);

    ++g_readersWaiting;

    // reading

    std::cout << "\n reader #" << i << " is reading data = " << g_sharedData << '\n';

    // end reading

    --g_readersWaiting;

    while(g_readersWaiting > 0)

        cond.wait(lg);

    cond.notify_one();

}


void writer(int i)

{

    std::unique_lock<std::mutex> lg{mu};

    while(g_writerWaiting)

        cond.wait(lg);

    // writing

    std::cout << "\n writer #" << i << " is writing\n";

    g_sharedData += i * 10;

    // end writing

    g_writerWaiting = true;

    while(g_readersWaiting > 0)

        cond.wait(lg);

    g_writerWaiting = false;

    cond.notify_all();

}//lg.unlock()



int main()

{

    std::thread reader1{reader, 1};

    std::thread reader2{reader, 2};

    std::thread reader3{reader, 3};

    std::thread reader4{reader, 4};

    std::thread writer1{writer, 1};

    std::thread writer2{writer, 2};

    std::thread writer3{writer, 3};

    std::thread writer4{reader, 4};


    reader1.join();

    reader2.join(); 

    reader3.join();

    reader4.join();

    writer1.join();

    writer2.join();

    writer3.join();

    writer4.join();


    return(0);

}


查看完整回答
反对 回复 2019-11-27
  • 3 回答
  • 0 关注
  • 285 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号