Концепция многопоточного приложения - PullRequest
2 голосов
/ 03 марта 2010

У меня небольшое архитектурное сомнение относительно организации кода в отдельных функциональных единицах (скорее всего, в потоках?). Разрабатываемое приложение должно выполнять следующие задачи:

  1. Отображение некоторых изображений на экране (например, слайд-шоу)
  2. Считывание данных с внешнего устройства через порт USB
  3. Сопоставить полученные данные с соответствующим изображением (стимул)
  4. Провести анализ данных
  5. График результатов анализа данных

Моими мыслями было организовать приложение в следующие модули:

  1. Тема с графическим интерфейсом (+ слайд-шоу изображений)
  2. USB-поток, буферизующий полученные данные
  3. Поток для анализа / построения данных (основной поток GUI не должен блокироваться при отображении данных, которые могут занять больше времени)

Итак, что вы вообще думаете об этой концепции? Есть ли что-то еще, что, по вашему мнению, могло бы быть лучше в этом конкретном сценарии?

Ответы [ 6 ]

3 голосов
/ 03 марта 2010

Из-за того, как работает Windows API, особенно в отношении пользовательского ввода и владения окнами. Вы действительно можете сделать пользовательский интерфейс только в одном потоке. Если вы попытаетесь использовать несколько потоков, они просто блокируют друг друга, и одновременно запускается только 1 поток. Есть некоторые специальные исключения, но вы должны быть настоящим мастером API, чтобы реализовать его.

Итак.

  1. Поток GUI, владеет окном и обрабатывает весь пользовательский ввод.
  2. Тема прослушивания USB, вы бы лучше меня знали, имеет ли это смысл
  3. Поток (ы) для анализа / построения данных, еще раз, я не могу говорить об этом, но я скептически отношусь к тому, что они действительно будут работать одновременно. Кажется более вероятным, что это будет проанализировано, а затем подготовить 1 поток.
  4. Поток для рендеринга кадров для слайд-шоу.

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

3 голосов
/ 03 марта 2010

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

Для # 3 вы можете обойтись без какой-либо методологии асинхронного ввода-вывода, так что вам не нужно выделять поток опроса. Не уверен, что вы можете сделать это с USB, но вы, безусловно, можете получить асинхронный ввод-вывод с последовательным и сетевым интерфейсами, так что стоит посмотреть.

Вероятно, это хорошая идея, чтобы перенести такие тяжелые задачи, как 4 и 5, в свою ветку. Если вы не выполняете анализ и графики одновременно, возможно, один поток для них обоих. Тем не менее, вы должны подумать, сколько процессорного времени потребуется для этих действий. Если анализ и построение наихудшего случая занимает намного меньше половины секунды, вы можете просто выполнить эти действия с помощью вызова из графического интерфейса. И наоборот, если есть случаи, когда это займет больше времени, отдельный поток предпочтителен, потому что вашим пользователям не понравится медленный графический интерфейс.

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

2 голосов
/ 03 марта 2010

Многое зависит от того, сколько задействовано в выполнении 3 (Провести некоторый анализ данных.) И 4 (Провести анализ данных.)

Мои инстинкты были бы:

Определенно есть отдельный поток для чтения данных с USB. Если предположить, что 3 зависит от чтения данных, то я бы сделал 3 в том же потоке, что и чтение данных. Это упростит передачу сигналов в графический интерфейс, когда данные будут готовы. Это также предполагает, что обработка выполняется быстро и не блокирует порт USB (как это читается? Порты завершения ввода-вывода?). Если обработка занимает время, вам нужен отдельный поток.

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

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

1 голос
/ 03 марта 2010

Не могу удержаться от мысли, что вы, возможно, идете сюда немного за борт. USB-порт не может действительно доставлять данные ужасно быстро - его теоретическая пропускная способность составляет всего 480 Мбит / с, и на самом деле, это довольно редкое USB-устройство, которое действительно может быть очень близко к этому.

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

Мне кажется, что главное, что у вас есть хорошие шансы на выигрыш, это построение графиков данных после их обработки. Возможно, стоит рассмотреть что-то вроде OpenGL или DirectX Graphics для рисования. Особенно, если вы производите довольно мало продукции, это может значительно улучшить скорость. В идеальной ситуации несколько потоков могут умножить вашу скорость на количество доступных ядер - обычно 2 или 4 на современных машинах. Вывод результатов, вероятно, будет самой медленной частью работы, и аппаратное ускорение может легко ускорить это значительно более значительным фактором - 10-кратное ниже, чем обычно можно ожидать, а 100-кратное является довольно распространенным.

1 голос
/ 03 марта 2010

Если вы используете Builder 2009, вы должны взглянуть на TThread.В нем есть кое-что для упрощения кодирования потоков.

1 голос
/ 03 марта 2010

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

Я бы проверил Boost и Boost :: Thread . Это не только делает ваш код более переносимым, но я не работал с более легкой библиотекой для многопоточности.

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