views:

394

answers:

2

Hello, I'm looking for a way to use pthread rwlock structure with conditions routines in C++.

I have two questions:

First: How is it possible and if we can't, why ?

Second: Why current POSIX pthread have not implemented this behaviour ?

To understand my purpose, I explain what will be my use: I've a producer-consumer model dealing with one shared array. The consumer will cond_wait when the array is empty, but rdlock when reading some elems. The producer will wrlock when adding(+signal) or removing elems from the array.

The benefit of using rdlock instead of mutex_lock is to improve performance: when using mutex_lock, several readers would block, whereas using rdlock several readers would not block.

A: 

For what you want, you need to just have 1 set of rwlock and 1 set of mutex/cond variable, pseudo code (though you'll need the usual loops on the posix cond variables)

consumer() {

  get_readlock();
  if(array_empty()) {
    release_readlock();
    grab_mutex();
    wait_on_condition();
    release_mutex();
    get_readlock();
  }
  process_elements();
  release_readlock();
}

producer()
{
  get_writelock();
  get_mutex();
  insert_elements();
  signal_condition();
  release_mutex();
  release_writelock();
}

I'd guess condition variables only works with mutexes, because waiting or signalling a conditions needs mutual exclusiveness.

nos
Warning, this solution could be lead to a big issue: Between first release_readlock and first grab_mutex, the consumer could give the hand to the producer and this one can fill the array and signal to nobody. If its happen, when the consumer actually does the wait_on_condition, it could be blocked, waiting a signal already sent by the producer.
Doomsday
A: 

I assume that by "conditions", you mean "conditional variables". They're different things.

No, you cannot use a rwlock when waiting on a conditional variable. I cannot answer as to the "why", but that's the way POSIX has decided to do it. Perhaps just to keep things simple.

You can still get the behavior you want, however, by making your own rwlock class by using only a mutex and 2 conditional variables without using a POSIX rwlock:

getReadLock():
     lock(mutex)
     while(array.empty())
         wait(readersCondVar, mutex)
     readers++;
     unlock(mutex)       

releaseReadLock():
     lock(mutex)
     if (--readers == 0)
           broadcast(writerCondVar, mutex) // or signal, if only 1 producer
     unlock(mutex)

readerThread:
     forever() {
         getReadLock()
         read()
         releaseReadLock()
      }

getWriteLock():
     lock(mutex)
     while(readers) {
         wait(writerCondVar, mutex)
     }

releaseWriteLock():
     broadcast(readersCondVar, mutex)
     unlock(mutex)

writerThread():
      forever() {
         getWriteLock()
         write()
         releaseWriteLock()
      }

Simple and does what you want.

RarrRarrRarr
It's simple and does what I want! I wanted a way to reuse pthread rwlock with condvar, but I'm probably wrong :-)
Doomsday