Большинство ответов выше говорят о производительности и одновременной работе.Я собираюсь подойти к этому под другим углом.
Давайте рассмотрим, скажем, упрощенную программу эмуляции терминала.Вы должны сделать следующее:
- следить за входящими символами из удаленной системы и отображать их
- следить за вещами, поступающими с клавиатуры, и отправлять их в удаленную систему
(Реальные эмуляторы терминала делают больше, в том числе потенциально отображают то, что вы печатаете на дисплее, но сейчас мы пропустим это.)
Теперь цикл для чтения изПульт ДУ прост, согласно следующему псевдокоду:
while get-character-from-remote:
print-to-screen character
Цикл для мониторинга клавиатуры и отправки также прост:
while get-character-from-keyboard:
send-to-remote character
Проблема, однако, в том, что у вас естьсделать это одновременно.Код теперь должен выглядеть примерно так, если у вас нет многопоточности:
loop:
check-for-remote-character
if remote-character-is-ready:
print-to-screen character
check-for-keyboard-entry
if keyboard-is-ready:
send-to-remote character
Логика, даже в этом намеренно упрощенном примере, который не учитывает сложность обмена данными в реальном мире, заключается вдовольно запутанный.Однако при многопоточности даже на одном ядре две петли псевдокода могут существовать независимо друг от друга, не чередуя свою логику.Поскольку оба потока будут в основном связаны с вводом-выводом, они не будут сильно нагружать ЦП, даже если они, строго говоря, потребляют больше ресурсов ЦП, чем интегрированный цикл.
Теперь, конечно, использование в реальных условиях сложнее, чем выше.Но сложность интегрированного цикла возрастает по экспоненте, поскольку вы добавляете больше проблем в приложение.Логика становится все более фрагментированной, и вы должны начать использовать методы, такие как конечные автоматы, сопрограммы и т. Д., Чтобы сделать вещи управляемыми.Управляемый, но не читаемый.Многопоточность делает код более читабельным.
Так почему бы вам не использовать многопоточность?
Что ж, если ваши задачи связаны с ЦП, а не с вводом / выводом, многопоточность фактически замедляет работу вашей системы.,Производительность пострадает.Много, во многих случаях.(«Перебрасывание» является распространенной проблемой, если вы отбрасываете слишком много потоков, связанных с процессором. В результате вы тратите больше времени на изменение активных потоков, чем на выполнение содержимого самих потоков.) Кроме того, одна из причин, по которой логика вышетак просто, что я очень сознательно выбрал упрощенный (и нереальный) пример.Если вы хотите отобразить то, что было напечатано на экране, тогда вы получаете новый мир боли, когда вводите блокировку общих ресурсов.С одним общим ресурсом это не такая большая проблема, но она начинает становиться все больше и больше, поскольку у вас появляется больше ресурсов для совместного использования.
Итак, в конце концов, многопоточность - это многое.Например, речь идет о том, чтобы сделать связанные с вводом / выводом процессы более отзывчивыми (даже если они менее эффективными в целом), как уже говорили некоторые.Это также облегчает выполнение логики (но только если вы минимизируете общее состояние).Речь идет о многих вещах, и вы должны решить, перевешивают ли его преимущества его недостатки в каждом конкретном случае.