Нужна ли блокировка чтения-записи для этого варианта использования?

Мой вопрос похож на эту тему, однако я уверен, что вывод, сделанный в данной теме, применим здесь.

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

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

Моя текущая реализация выглядит следующим образом

  1. Статус Thread Main() Взять ReadLock Прочитать имя группы приложений Снять ReadLock

    отправить статус

  2. Поток обновлений Main() Взят блокировку записи Обновить имя группы Снять блокировку записи

Однако из-за большого количества отправляемых обновлений я боюсь, что могу привести к снижению производительности при большой нагрузке. Поэтому я работаю над следующей реализацией, но я не уверен, что это сработает.

Новая предлагаемая реализация

  1. Поток-отправитель содержит char* ptr, char[1024] primaryData, char[1024]secondaryData.
  2. При первом запуске приложения имя группы обновляется в primaryData, а ptr указывает на primaryData.
  3. Всякий раз, когда поток обновления имеет событие обновления, он будет проверять, если (ptr == primaryData) Скопировать новое имя приложения в вторичные данные ptr = вторичные данные else Скопировать новое имя приложения в первичные данные. ptr = первичные данные
  4. Поток состояния всегда будет использовать данные, указанные ptr, для отправки состояния. Поток состояния в конечном итоге получит обновленный ptr (учитывая когерентность кеша) и начнет передачу новых данных.

Здесь следует учесть несколько моментов. 1. Это нормально, даже если новые данные не будут мгновенно доступны для потока состояния 2. Я не хочу, чтобы программа вылетала из-за неправильного доступа к памяти.

Друзья, подскажите, поможет ли вышеизложенная логика избежать блокировки чтения-записи.


person Amey Jah    schedule 28.05.2012    source источник
comment
Вы должны начать с вашей текущей реализации и оптимизировать ПОСЛЕ того, как вы заметите снижение производительности. Преждевременная оптимизация (почти) всегда плоха :)   -  person anthonyvd    schedule 28.05.2012
comment
@pwny Я согласен. Но даже во время нагрузочного теста я не смог бы сгенерировать фактическую нагрузку качества производства. Поэтому я хочу избежать неоптимизированного кодирования.   -  person Amey Jah    schedule 28.05.2012
comment
@AmeyJah: Тогда ваше нагрузочное тестирование ошибочно. Он должен быть в состоянии создавать нагрузки, более высокие, чем все, что вы, вероятно, увидите в производственной среде.   -  person NPE    schedule 28.05.2012


Ответы (2)


не могли бы вы сказать мне, поможет ли приведенная выше логика избежать блокировки чтения-записи.

Нет, эта логика не позволит вам избежать блокировки. Предлагаемая схема полна условий гонки.

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

Если — и только если — окажется, что это приводит к неприемлемому конфликту блокировок, вам следует подумать о дальнейшей оптимизации.

person NPE    schedule 28.05.2012

Блокировка чтения-записи в сценарии с одним читателем и одним писателем ничем не отличается от простого старого мьютекса. Просто используйте мьютекс.

person Tudor    schedule 28.05.2012