简单的读写锁。写优先

Posted 琴鸟

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了简单的读写锁。写优先相关的知识,希望对你有一定的参考价值。

1.非常简单的,一线程写,一线程读。 读线程阻塞,直到写线程通知读线程。简单,重要是基本不会用错。

#include <stdio.h>
#include <string>
#include <iostream>
#include <memory>
#include <mutex>
#include <condition_variable>
#include <vector>
#include <thread>
#include <unistd.h>

using namespace std;

class book
{
public:
    book():canread(false){}
    
    void Write(const vector<string>& _v)
    {
        unique_lock<mutex> w_mtx(book_mtx,defer_lock);//控制代码1
        w_mtx.lock();//控制代码2
        
        
        
        cout<<this_thread::get_id()<<"  :writer get lock, and start write"<<endl;
        
        cout<<"before write.vector size:"<<books.size()<<endl;
        
        
        for(size_t i=0;i<_v.size();i++)
        {
            books.push_back(_v[i]);
        }
        
        cout<<"after write.vector size:"<<books.size()<<endl;
    
        cout<<this_thread::get_id()<<"  :write end and ready set canread=true, and notify all"<<endl;
        
        canread=true;////控制代码3
        w_mtx.unlock();//控制代码4
        book_cv.notify_all();//控制代码5
    }
    
    void Read()
    {
        unique_lock<mutex> r_mtx(book_mtx,defer_lock);//控制代码1
        r_mtx.lock();//控制代码2
        while(!canread)//控制代码3
        {
            book_cv.wait(r_mtx);//控制代码4
        }
        cout<<this_thread::get_id()<<"  :reader get lock.and set value=‘‘ , canread=false "<<endl;
        
        cout<<"before read.vector size:"<<books.size()<<endl;
        vector<string> empty;
        empty.swap(books);
        cout<<"after read.vector size:"<<books.size()<<endl;
    
        
        canread=false;//控制代码5
        r_mtx.unlock();//控制代码6
    }
    
    
private:
    vector<string> books;
    mutex book_mtx;
    condition_variable book_cv;
    bool canread;
};


//写,设置为15秒一次.
void wrtie2book(book& _v)
{
    for(;;)
    {
        vector<string> newbooks;
        newbooks.push_back("aaa");
        newbooks.push_back("bbb");
        newbooks.push_back("ccc");
        _v.Write(newbooks);
        sleep(15);
    }
}

//读是只要可以读就一直读.不能读就阻塞在县城.等待生产者放入数据.
void read2book(book& _v)
{
    for(;;)
    {
        _v.Read();
    }
}


int main()
{
    book mybooks;
    

    thread read1(read2book,std::ref(mybooks));
    read1.detach();

    thread wrtie2(wrtie2book,std::ref(mybooks));
    wrtie2.detach();

    string cmd;
    cin>>cmd;
    return 0;
}

2)如果有多线程读,很多场合下是,每个线程处理一条。

代码也是基本一魔一样。只要读线程也设置一下canread 。同样简单,不出错。

#include <stdio.h>
#include <string>
#include <iostream>
#include <memory>
#include <mutex>
#include <condition_variable>
#include <vector>
#include <thread>
#include <unistd.h>

using namespace std;


class book
{
public:
    book():canread(false){}
    
    void Write(const vector<string>& _v)
    {
        unique_lock<mutex> w_mtx(book_mtx,defer_lock);//控制代码1
        w_mtx.lock();//控制代码2
        
        
        
        cout<<this_thread::get_id()<<"  :writer get lock, and start write"<<endl;
        
        cout<<"before write.vector size:"<<books.size()<<endl;
        
        
        for(size_t i=0;i<_v.size();i++)
        {
            books.push_back(_v[i]);
        }
        
        cout<<"after write.vector size:"<<books.size()<<endl;
    
        cout<<this_thread::get_id()<<"  :write end and ready set canread=true, and notify all"<<endl;
        
        
        if(books.size()>0)//控制代码5
        {
            canread=true;//控制代码6
        }
        else
        {
            canread=false;//控制代码7
        }
        w_mtx.unlock();//控制代码4
        book_cv.notify_all();//控制代码5
    }
    
    void Read()
    {
        unique_lock<mutex> r_mtx(book_mtx,defer_lock);//控制代码1
        r_mtx.lock();//控制代码2
        while(!canread)//控制代码3
        {
            book_cv.wait(r_mtx);//控制代码4
        }
        
        
        cout<<this_thread::get_id()<<"  :reader get lock.and get one item  "<<endl;
        
        cout<<"before read.vector size:"<<books.size()<<endl;
        if(books.size()>0)
        {
            books.erase(books.begin());
        }
        
        
        cout<<"after read.vector size:"<<books.size()<<endl;
        cout<<this_thread::get_id()<<"  :reader check size ,and set canread true or false"<<endl;
        
        
        if(books.size()>0)//控制代码5
        {
            canread=true;//控制代码6
        }
        else
        {
            canread=false;//控制代码7
        }
        r_mtx.unlock();//控制代码8
    }
    
    
private:
    vector<string> books;
    mutex book_mtx;
    condition_variable book_cv;
    bool canread;
};


//写,设置为15秒一次.
void wrtie2book(book& _v)
{
    for(;;)
    {
        vector<string> newbooks;
        newbooks.push_back("aaa");
        newbooks.push_back("bbb");
        newbooks.push_back("ccc");
        _v.Write(newbooks);
        sleep(15);
    }
}

//读是只要可以读就一直读.不能读就阻塞在县城.等待生产者放入数据.
void read2book(book& _v)
{
    for(;;)
    {
        _v.Read();
    }
}


int main()
{
    book mybooks;
    

    thread read1(read2book,std::ref(mybooks));
    read1.detach();
    
    thread read2(read2book,std::ref(mybooks));
    read2.detach();
    
    thread read3(read2book,std::ref(mybooks));
    read3.detach();


    thread wrtie2(wrtie2book,std::ref(mybooks));
    wrtie2.detach();

    string cmd;
    cin>>cmd;
    return 0;
}

 

以上是关于简单的读写锁。写优先的主要内容,如果未能解决你的问题,请参考以下文章

Linux同步技术之读写锁

pthread之读写锁

java中ReentrantReadWriteLock读写锁的使用

读写锁

Java 线程锁机制 -Synchronized Lock 互斥锁 读写锁

线程同步互斥锁和读写锁的区别和各自适用场景