Используя pthread условную переменную с rwlock

Я ищу способ использовать pthread rwlock структура со стандартными программами условий в C++.

У меня есть два вопроса:

Во-первых: Как возможно и если мы не можем, почему?

Во-вторых: Почему текущий POSIX pthread не реализовал это поведение?

Для понимания моей цели я объясняю, что будет моим использованием: у меня есть контакт модели производителя-потребителя с одним общим массивом. Потребитель будет cond_wait, когда массив будет пуст, но rdlock при чтении некоторого elems. Производитель будет wrlock при добавлении (+signal) или удалении elems от массива.

Преимущество использования rdlock вместо mutex_lock состоит в том, чтобы улучшить производительность: при использовании mutex_lock, заблокировались бы несколько читателей, тогда как использование rdlock несколько читателей не заблокируется.

9
задан Doomsday 23 April 2010 в 15:53
поделиться

2 ответа

Я предполагаю, что под «условиями» вы подразумеваете «условные переменные». Это разные вещи.

Нет, вы не можете использовать rwlock при ожидании условной переменной. Я не могу ответить на вопрос «почему», но POSIX решил сделать это именно так. Возможно, просто для простоты.

Вы по-прежнему можете добиться желаемого поведения, создав свой собственный класс rwlock, используя только мьютекс и 2 условные переменные без использования rwlock POSIX:

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()
      }

Просто и делает то, что вы хотите.

6
ответ дан 4 December 2019 в 22:27
поделиться

Для того, что вы хотите, вам нужно иметь только 1 набор rwlock и 1 набор переменных mutex / cond, псевдокода (хотя вам понадобится обычные циклы для переменных posix cond)

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();
}

Я предполагаю, что переменные условия работают только с мьютексами, потому что ожидание или сигнализация условий требует взаимной исключительности.

0
ответ дан 4 December 2019 в 22:27
поделиться