首页 > 代码库 > 简单的读写锁。写优先

简单的读写锁。写优先

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=http://www.mamicode.com/‘‘ , 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;
}

 

简单的读写锁。写优先