# Pragma once /************************************ * ************** the Read efficiency of write-first-read locks is about twice slower than that of Windows srwlock, millions of read Locks require 156 ms (78 ms) of write efficiency, n times slower than Windows srwlock, and 1516 ms (62 ms) of millions of write locks) cksrwlock read/write lock automation (raiI mechanism) cautolockwrite lock automation (raiI mechanism) usage (code example): cksrwlock ksrwlock; void read () {cautolockread lock (ksrwlock); // todo: Read code} void write () {cautolockwrite lock (ksrwlock); // todo: code written }**************************** * ********************/# Include <cassert> class cksrwlock {public: void lockwrite () {// write wait count variable assert (m_refwritewaitcount> = 0); interlockedincrement (& encoding); // entercriticalsection (& m_cswrite) in the critical section; // unreadable resetevent (m_eventreadenable ); // mutex interlockedexchangeadd (& m_refcount,-m_clmax_read); // wait until all reads are completed while (m_refcount <0);} void unlockwrite () {// mutex long init = interlockedexchangeadd (& m_refco Unt, m_clmax_read); // write wait count variable long value = interlockeddecrement (& m_refwritewaitcount); Assert (value> = 0); // read setevent (m_eventreadenable ); // critical section leavecriticalsection (& m_cswrite);} // returns the number of concurrent read threads long lockread () {// optimized, using a write wait count variable, avoid direct waitif (0 = m_refwritewaitcount) {// mutex long iresult = interlockeddecrement (& m_refcount); If (iresult> 0) {// lock: n-> (n-1) return m_clmax_read-iresult;} else {interlo Ckedincrement (& m_refcount) ;}// basic process while (true) {// enter the kernel wait if (wait_timeout = waitforsingleobject (m_eventreadenable, infinite) {return 0 ;} if (0 = m_refwritewaitcount) {// mutex long iresult = interlockeddecrement (& m_refcount); If (iresult> 0) {// lock: N-> (n-1) return m_clmax_read-iresult;} else {interlockedincrement (& m_refcount) ;}}// number of concurrent read threads returned (0 indicates lock failure) Long trylockread (DWORD dwtick = 0) {// excellent To avoid direct waitif (0 = m_refwritewaitcount) {// mutex long iresult = interlockeddecrement (& m_refcount); If (iresult> 0) {// lock: N-> (n-1) return m_clmax_read-iresult;} else {interlockedincrement (& m_refcount) ;}} if (0 = dwtick) return 0; // basic process // enter the kernel and wait for if (wait_timeout = waitforsingleobject (m_eventreadenable, dwtick) {return 0;} If (0 = m_refwritewaitcount) {// mutex long iresult = interlocked Decrement (& m_refcount); If (iresult> 0) {// lock: N-> (n-1) return m_clmax_read-iresult ;} else {interlockedincrement (& m_refcount) ;}} return 0 ;}void unlockread () {// mutually exclusive interlockedincrement (& m_refcount);} public: cksrwlock (void ): m_refcount (m_clmax_read), m_refwritewaitcount (0) {values (& m_cswrite); m_eventreadenable =: createevent (null, true, true, null); setevent (m_eventreadenable);} vi Rtual ~ Cksrwlock (void) {try {deletecriticalsection (& m_cswrite); closehandle (m_eventreadenable);} catch (...) {} protected: // The maximum number of concurrent reads will not exceed m_clmax_read. Static const longm_clmax_read = 1000000; // m_refcount: using interlocked funtions to access // 100000000-free // 0-one thread is writing // 100000000-n threads are readingvolatile longm_refcount; // n-n threads are waiting to wirtevolatile longm_refwritewaitcou NT; // once a thread to encode; // wait for writing completehandlem_eventreadenable;}; Class cautolockwrite {public: cautolockwrite (cksrwlock & CS, bool block = true, lpctstr szdebugmsg = NULL): m_cs (CS), m_bleaved (true), m_strdebugmsg (szdebugmsg) {If (Block) {lock () ;}} void lock () {If (m_bleaved) {m_cs.lockwrite (); m_bleaved = false; If (! M_strdebugmsg.empty () {// clog: Research (_ T ("wlock: % s lock <"), m_strdebugmsg.c_str () ;}}// sometimes we need release it as soon as possible, so just call leave (). void unlock () {If (! M_bleaved) {If (! M_strdebugmsg.empty () {// clog: Research (_ T ("wlock: % s unlock >>>>>>>>>>>>>>> "), m_strdebugmsg.c_str ();} m_cs.unlockwrite (); m_bleaved = true ;}// auto-releasevirtual ~ Cautolockwrite () {try {unlock ();} catch (...) {}} protected: // memberscksrwlock & m_cs; bool m_bleaved; tstringm_strdebugmsg; private: // No copy or assignmentcautolockwrite (const cautolockwrite &); cautolockwrite & operator = (const cautolockwrite &) ;}; class cautolockread {public: cautolockread (cksrwlock & CS, bool block = true): m_cs (CS), m_bleaved (true ), m_readthreadcount (0) {If (Block) {lock () ;}} bool trylock (DWORD DW Tick = 0) {assert (m_bleaved); If (m_bleaved) {m_readthreadcount = m_cs.trylockread (dwtick); If (0! = M_readthreadcount) {m_bleaved = false; return true ;}} return false;} void lock () {assert (m_bleaved); If (m_bleaved) {m_readthreadcount = m_cs.lockread (); m_bleaved = false ;}}// sometimes we need release it as soon as possible, so just call leave (). void unlock () {If (! M_bleaved) {m_cs.unlockread (); m_bleaved = true ;}} long getreadcount () const {return m_readthreadcount;} // auto-releasevirtual ~ Cautolockread () {try {unlock ();} catch (...) {}} protected: // memberscksrwlock & m_cs; bool m_bleaved; long m_readthreadcount; private: // No copy or assignmentcautolockread (const cautolockread &); cautolockread & operator = (const cautolockread &);};