read/write lock implementation using mutex only?

后端 未结 2 1854
爱一瞬间的悲伤
爱一瞬间的悲伤 2021-02-03 15:49

I was trying to implement read/write lock using mutex only (just for learning). Just when i thought i have covered all corner cases (as the program worked with variety of combin

相关标签:
2条回答
  • 2021-02-03 16:21

    You do not need a separate mutex "for data"; the whole construct will serve as the data lock, if its internal logic is correct. Instead, you could use two separate condition variables for readers and for writers, so that you can broadcast all waiting readers without affecting waiting writers. The code is below; you can also see that it's simpler this way. Besides, I added a destructor and fixed a bug in w_lock: the condition to wait should be (NoOfReaders!=0 || NoOfWriters!=0), and not &&.

    class rw_lock_t {
    
        int NoOfReaders;
        int NoOfWriters, NoOfWritersWaiting;
        pthread_mutex_t class_mutex;
        pthread_cond_t  reader_gate;
        pthread_cond_t  writer_gate;
    
    public:
    
        rw_lock_t()
        : NoOfReaders(0), NoOfWriters(0), NoOfWritersWating(0),
          class_mutex(PTHREAD_MUTEX_INITIALIZER),
          reader_gate(PTHREAD_COND_INITIALIZER),
          writer_gate(PTHREAD_COND_INITIALIZER)
        {}
        ~rw_lock_t()
        {
            pthread_mutex_destroy(&class_mutex);
            pthread_cond_destroy(&reader_gate);
            pthread_cond_destroy(&writer_gate);
        }
        void r_lock()
        {
            pthread_mutex_lock(&class_mutex);
            //while(NoOfWriters>0 || NoOfWritersWaiting>0) //Writer Preference
            while(NoOfWriters>0)
            {
                pthread_cond_wait(&reader_gate, &class_mutex);
            }
            NoOfReaders++;        
            pthread_mutex_unlock(&class_mutex);
        }
        void w_lock()
        {
            pthread_mutex_lock(&class_mutex);
            NoOfWritersWaiting++;
            while(NoOfReaders>0 || NoOfWriters>0)
            {
                pthread_cond_wait(&writer_gate, &class_mutex);
            }
            NoOfWritersWaiting--; NoOfWriters++;
            pthread_mutex_unlock(&class_mutex);
        }
        void r_unlock()
        {
            pthread_mutex_lock(&class_mutex);
            NoOfReaders--;
            if(NoOfReaders==0 && NoOfWritersWaiting>0)
                pthread_cond_signal(&writer_gate);
            pthread_mutex_unlock(&class_mutex);
        }
        void w_unlock()
        {
            pthread_mutex_lock(&class_mutex);
            NoOfWriters--;
            if(NoOfWritersWaiting>0)
                pthread_cond_signal(&writer_gate);
            //else //Writer Preference - don't signal readers unless no writers
            pthread_cond_broadcast(&reader_gate);
            pthread_mutex_unlock(&class_mutex);
        }
    };
    
    0 讨论(0)
  • 2021-02-03 16:25
    class ReadWriteLock {
        mutex writeLock;
        mutex readLock;
        int readCount;
    public:
        ReadWriteLock() {
            readCount = 0;
        }
        void LockWrite() {
            writeLock.lock();
        }
        void UnlockWrite() {
            writeLock.unlock();
        }
        void LockRead() {
            lock_guard<mutex> lock(readLock);
            ++readCount;
            if (1 == readCount) {
                LockWrite();
            }
        }
        void UnlockRead() {
            lock_guard<mutex> lock(readLock);
            --readCount;
            if (0 == readCount) {
                UnlockWrite();
            }
        }
    };
    

    As Alexey pointed out, if the last read thread to UnlockWrite isn't the first read thread to LockWrite, the behavior is undefined. See std::mutex::unlock http://www.cplusplus.com/reference/mutex/mutex/unlock/ Windows ReleaseMutex: http://msdn.microsoft.com/en-us/library/windows/desktop/ms685066(v=vs.85).aspx

    0 讨论(0)
提交回复
热议问题