Вопрос об использовании многопоточности для периодической и принудительной проверки обновлений программного обеспечения - PullRequest
1 голос
/ 04 августа 2011

Я работаю над приложением, в котором есть основной поток, выполняющий некоторую работу (цикл обработки сообщений пользовательского интерфейса и т. Д.), Но мне также нужен второй поток, который будет периодически проверять наличие доступных для загрузки обновлений. Я также хотел бы, чтобы основной поток мог попросить вторичный поток принудительно проверить наличие обновлений, а дополнительный поток - у основного потока для подтверждения загрузки обновлений.

У меня не так много опыта работы с IPC и многопоточностью в реальных ситуациях, поэтому я не уверен, как мне следует разрабатывать это. Я хотел бы, чтобы в конечном итоге эта работа работала как на Windows, так и на POSIX, но сейчас давайте сосредоточимся на POSIX. Вот моя идея до сих пор:

Псевдокод вторичной резьбы:

repeat forever:
  check_for_updates()

  if (are_any_updates()) {
    put the list of available updates on some message queue
    send signal SIGUSER1 to main thread
    wait for response from that message queue
    if (response is positive) download_updates()
  }
  unblock signal SIGUSER1 on secondary thread
  Sleep(one hour)
  block signal SIGUSER1
  if (any_signal_was_received_while_sleeping)
   any_signal_was_received_while_sleeping := false
   Sleep(one more hour)

Обработчик SIGUSER1 во вторичном потоке (основной поток запросил у нас проверку обновлений):

  block signal SIGUSER1 (making sure we don't get signal in signal)
  any_signal_was_received_while_sleeping := true
  check_for_updates()
  ...
  unblock signal SIGUSER1

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

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

Любое мнение приветствуется, включая советы о том, какие функции IPC следует использовать в Windows (может быть, RPC вместо сигналов?). Я мог бы полностью исключить использование очереди сообщений, если бы остановился на потоках, но я мог бы вместо этого рассмотреть использование процессов. Я буду четко использовать темы в Windows, но пока не уверен насчет POSIX.

1 Ответ

1 голос
/ 04 августа 2011

Вам настоятельно рекомендуется использовать boost :: thread для решения вашей проблемы.Это гораздо более понятно, чем непосредственное использование posix, и является кроссплатформенным.Потратьте время, чтобы использовать более качественный инструмент, и в итоге вы сэкономите немало усилий.

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

РЕДАКТИРОВАТЬ:
Вы можете сделать почти все с правильным использованием мьютексов и условных переменных.Другой совет - инкапсулировать ваши потоки внутри объектов класса .Это позволяет вам писать функции, которые действуют на поток и его данные.В вашем случае основной поток может иметь метод, подобный requestUpdateConfirmation (), внутри которого вы можете заблокировать вызывающий поток и подождать, пока основной поток обработает запрос, прежде чем освобождать вызывающую сторону.

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