Как я могу синхронизировать доступ к базе данных между потоком записи и потоком чтения?

Моя программа имеет два потока:

  1. Основной поток выполнения, который обрабатывает ввод данных пользователем и стоит в очереди записи базы данных
  2. Служебный поток, который просыпается каждую секунду и сбрасывает записи к базе данных

В основном потоке я иногда должен делать чтения на базе данных. Когда это происходит, производительность не важна, но правильность. (В идеальном мире я читал бы из кэша, не делая распространение в прямом и обратном направлениях к базе данных - но давайте отложим это ради обсуждения.)

Как я удостоверяюсь, что основной поток видит корректное / статическая база данных?

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

То, что я действительно хочу, является своего рода взаимным исключением, которое позволяет основному потоку выполнения продолжиться только ПОСЛЕ ТОГО, КАК взаимное исключение было захвачено и выпущено однажды. Такая вещь существует? Что лучший способ состоит в том, чтобы решить эту проблему?

ОБНОВЛЕНИЕ: После проведения некоторого дополнительного исследования я мог бы использовать Условную Переменную Повышения для рассмотрения этой проблемы. Или это, или просто стиснуло зубы и кэширует мои записи. Спасибо за обратную связь!

6
задан Runcible 3 April 2010 в 00:19
поделиться

3 ответа

Если у вас не более одного основного потока выполнения (т. Е. Единственный поток, который будет отправлять записи в рабочий поток, это тот же поток который будет читать из базы данных), тогда вы, вероятно, можете просто иметь простую переменную / функцию «ожидающих записей», которую вы можете проверить перед отправкой чтения , и спин-блокировку или ожидание сигнала, пока записи не будут покраснел. Похоже, вам не нужно будет выполнять какую-либо блокировку или синхронизацию операций записи, если их можно просто поставить в очередь для обработки рабочим потоком.

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

1
ответ дан 17 December 2019 в 00:06
поделиться

Возможны несколько решений:

  • Пусть каждый поток открывает собственное соединение d / b и использует его исключительно
  • Используйте одно соединение, но каждый поток владеет мьютексом для доступа к нему.

Я не вижу проблем со вторым выбором. В чем вред, когда промывать нечего?

3
ответ дан 17 December 2019 в 00:06
поделиться

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

Решение, которое вы можете попробовать, - это значение состояния атомарной базы данных: вы выполняете обработку, затем сравниваете со значением атомарного состояния, чтобы убедиться, что вы читаете из базы данных, которая находится в том же состоянии, что и в момент начала чтения. Если что-то другое, вы начинаете заново. Это может быть голодом, но это отдельная тема.

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

3
ответ дан 17 December 2019 в 00:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: