Лучшие практики в отношении количества потоков в приложениях с графическим интерфейсом - PullRequest
4 голосов
/ 23 сентября 2008

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

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

Это часто встречается? Является ли это общепринятой философией для графического дизайна приложений?

А если так, то почему?

[править]

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

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

Ответы [ 9 ]

5 голосов
/ 23 сентября 2008

Вообще говоря, рамки GUI не являются поточно-ориентированными. Для таких вещей, как Swing (Java GUI API), только один поток может обновлять пользовательский интерфейс (или могут случиться плохие вещи). Только один поток обрабатывает события диспетчеризации. Если у вас есть несколько потоков, обновляющих экран, вы можете получить некрасивое мерцание и неправильный рисунок.

Это не означает, что приложение должно быть однопоточным. Конечно, есть обстоятельства, когда вы не хотите, чтобы это имело место. Если вы щелкнете по кнопке, которая вычисляет пи до 1000 цифр, вы не хотите, чтобы пользовательский интерфейс был заблокирован, а кнопка была нажата в течение следующих нескольких дней. Это когда такие вещи, как SwingWorker пригодятся. Он состоит из двух частей: doInBackground (), который выполняется в отдельном потоке, и done (), который вызывается потоком, который обрабатывает обновление пользовательского интерфейса через некоторое время после завершения потока doInBackground. Это позволяет быстро обрабатывать события или события, которые могут обрабатываться в фоновом режиме в течение длительного времени, при этом единственный поток обновляет экран.

5 голосов
/ 23 сентября 2008

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

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

3 голосов
/ 23 сентября 2008

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

Многие программисты с графическим интерфейсом, с которыми я работал в прошлом, боятся потоков, потому что они "трудные". В некоторых GUI-средах, таких как Delphi VCL, есть предупреждения об использовании VCL из нескольких потоков, и это пугает некоторых людей (другие воспринимают это как вызов;))

Одним из интересных примеров многопоточного кодирования GUI является API BeOS. Каждое окно в приложении получает свой собственный поток. По моему опыту, приложения BeOS стали более отзывчивыми, но программирование стало немного сложнее. К счастью, поскольку BeOS по умолчанию был разработан как многопоточный, в API было много вещей, которые облегчили бы задачу, чем в некоторых других ОС, которые я использовал.

2 голосов
/ 23 сентября 2008

Да.

Приложения с графическим интерфейсом должны минимизировать количество потоков, которые они используют по следующим причинам:

  1. Программирование потоков очень сложно и сложно
  2. Как правило, приложения с графическим интерфейсом выполняют максимум 2 вещи одновременно: а) реагируют на ввод пользователя и б) выполняют фоновую задачу (например, загрузку данных) в ответ на действие пользователя или ожидаемое действие пользователя

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

Есть, конечно, исключения из правила.

2 голосов
/ 23 сентября 2008

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

1 голос
/ 23 сентября 2008

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

Поскольку закон Мура меняется с увеличением количества ядер, это изменится, и, надеюсь, будут развиваться рамки программирования, которые помогут нам более эффективно использовать потоки в зависимости от количества ядер, доступных для программы, таких как TPL .

1 голос
/ 23 сентября 2008

Чем больше потоков в приложении (как правило), тем сложнее решение. Попытка свести к минимуму количество потоков, используемых в графическом интерфейсе, создает меньше потенциальных областей для проблем.

Другая проблема - самая большая проблема в дизайне GUI: человек. Люди печально известны своей способностью в хотеть делать несколько вещей одновременно. Пользователи имеют привычку быстро нажимать несколько кнопок / элементов управления, чтобы попытаться сделать что-то быстрее. Компьютеры, как правило, не могут справиться с этим (это связано только с очевидной способностью GUI поддерживать работу с использованием нескольких потоков), поэтому для минимизации этого эффекта GUI будет реагировать на входные данные в порядке поступления в один поток. При этом графический интерфейс вынужден ждать, пока системные ресурсы не будут свободными, пока он не сможет двигаться дальше. Поэтому устранение всех неприятных тупиковых ситуаций, которые могут возникнуть. Очевидно, что если логика программы и графический интерфейс пользователя находятся в разных потоках, то это выходит за рамки.

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

1 голос
/ 23 сентября 2008

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

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

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

0 голосов
/ 23 сентября 2008

Как правило, все оконные сообщения от оконного менеджера / ОС отправляются в одну очередь, поэтому естественно, чтобы все элементы пользовательского интерфейса были в одном потоке. Некоторые платформы, такие как .Net, фактически генерируют исключения, если вы пытаетесь получить прямой доступ к элементам пользовательского интерфейса из потока, отличного от потока, который его создал.

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