Какие виды приложений должны быть многопоточными? - PullRequest
23 голосов
/ 18 января 2009

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

Ответы были бы наилучшими, если бы в форме одного заявления на пост таким образом наиболее подходящее всплыло бы наверх.

Ответы [ 14 ]

20 голосов
/ 18 января 2009

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

Если ваше целевое оборудование одноядерное / ядро, вы вряд ли увидите какие-либо улучшения с многопоточными решениями (так как в любом случае выполняется только один поток!)

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

Некоторые примеры

  • Обработка изображения часто может выполняться параллельно (например, разделить изображение на 4 и выполнить работу в 1/4 времени), но это зависит от того, какой алгоритм запускается, чтобы увидеть, имеет ли это смысл .
  • Рендеринг анимации (из 3DMax и т. Д.) Массивно параллелен, поскольку каждый кадр может быть представлен независимо друг от друга - это означает, что 10 или 100 компьютеров могут быть объединены в цепочку, чтобы выручить.
  • GUI программирование часто помогает иметь по крайней мере два потока при выполнении чего-то медленного, например обработка большого количества файлов - это позволяет интерфейсу оставаться отзывчивым, в то время как работник выполняет тяжелую работу (в качестве примера можно привести BackgroundWorker)

Графические интерфейсы являются интересной областью, поскольку «отзывчивость» интерфейса может поддерживаться без многопоточности, если рабочий алгоритм поддерживает основной графический интерфейс «живым», предоставляя ему время в терминах Windows API (до .NET и т. Д.) это может быть достигнуто примитивным циклом и не требует многопоточности:

MSG msg;
while(GetMessage(&msg, hwnd, 0, 0))
{
    TranslateMessage(&msg);
    DispatchMessage(&msg);

    // do some stuff here and then release, the loop will come back
    // almost immediately (unless the user has quit)
}
15 голосов
/ 18 января 2009

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

  1. Запуск процесса с несколькими потоками
  2. Запуск нескольких процессов

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

Проблема с несколькими потоками состоит в том, что они обычно сложнее кодировать, чем несколько процессов.

8 голосов
/ 18 января 2009

Существует три класса причин, по которым будет применяться многопоточность:

  • Выполнение параллелизма для повышения производительности вычислений : Если у вас есть проблема, которая может быть разбита на части, и у вас также имеется более одного доступного исполнительного блока (ядра процессора), тогда распределение частей в отдельные потоки путь к одновременному использованию двух или более ядер.
  • Параллельность операций ЦП и операций ввода-вывода : Это похоже на первое мышление, но в этом случае цель состоит в том, чтобы сохранить занятость ЦП и также перемещение операций ввода-вывода (т. Е. Дискового ввода-вывода) параллельно, а не чередуясь между ними.
  • Дизайн и отзывчивость программы : Многие типы программ могут использовать многопоточность как преимущество при разработке программы, чтобы сделать программу более отзывчивой для пользователя. Например, программа может взаимодействовать через графический интерфейс, а также делать что-то в фоновом режиме.

Конкретные примеры:

  • Microsoft Word : редактировать документ, пока фоновая грамматика и проверка орфографии работают, чтобы добавить все зеленые и красные подчеркивания волнистости.
  • Microsoft Excel : автоматический пересчет фона после редактирования ячейки
  • Веб-браузер : отправка нескольких потоков для параллельной загрузки каждой из нескольких ссылок HTML во время загрузки одной страницы. Ускоряет загрузку страницы и максимально увеличивает пропускную способность TCP / IP.
5 голосов
/ 18 января 2009

В наши дни ответом должно быть Любое приложение, которое может быть .

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

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

4 голосов
/ 18 января 2009

В основном есть две причины многопоточности:

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

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

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

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

Как еще одно замечание, для # 1 потоки Python не будут работать, потому что в Python одновременно может выполняться только одна инструкция python (известная как GIL или Global Interpreter Lock). Я использую это в качестве примера, но вы должны проверить свой язык. В python, если вы хотите выполнять параллельные вычисления, вам нужно выполнять отдельные процессы.

3 голосов
/ 18 января 2009

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

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

Edit:

Речь не идет об улучшении производительности, поскольку все потоки (возможно, 5, может быть, 10) в основном спят. Однако это является огромным улучшением для структуры программы, когда различные параллельные процессы могут быть закодированы как последовательности действий, которые не знают друг о друге. У меня очень плохие воспоминания о временах 16-битной Windows, когда я создавал конечный автомат для каждой позиции машины, следил за тем, чтобы ничто не занимало больше нескольких миллисекунд, и постоянно передавал управление следующему конечному автомату. Когда бывали аппаратные события, которые нужно было обслуживать вовремя, а также вычисления, которые занимали время (например, FFT), тогда все становилось ужасно быстро.

3 голосов
/ 18 января 2009

Многие каркасы GUI являются многопоточными. Это позволяет вам иметь более отзывчивый интерфейс. Например, вы можете нажать кнопку «Отмена» в любое время, пока выполняется длинный расчет.

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

2 голосов
/ 18 января 2009

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

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

Пожалуйста, примите это как дополнительную информацию, а не попытку ответить на ваш вопрос.

1 голос
/ 18 января 2009

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

Некоторые примеры, которые я сделал, являются хорошими многопоточными кандидатами ..

  • запущенные сценарии (например, оценка производных акций, статистика)
  • массовое обновление файлов данных (например, добавление значения / записи в 10000 записей)
  • другие математические процессы
1 голос
/ 18 января 2009

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

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