简单的读写锁。写优先
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; }
以上是关于简单的读写锁。写优先的主要内容,如果未能解决你的问题,请参考以下文章
java中ReentrantReadWriteLock读写锁的使用