Подтвердить что ты не робот

Когда многопоточность не очень хорошая идея?

Недавно я работал над приложением, которое отправляло и получало сообщения через Ethernet и Serial. Затем мне было поручено добавить мониторинг дискретизации DIO. я throught,

"Нет причин прерывать основной поток, который участвует в сообщении обработки, я просто создаю другой поток, который контролирует DIO.

Это решение, однако, оказалось бедным. Иногда основной поток прерывается между последовательным сообщением "Отправить" и "Получать". Это прерывание нарушит сроки и, увы, сообщения будут потеряны (навсегда).

Я нашел другой способ контролировать DIO без использования другого потока, и Ethernet и последовательная связь были восстановлены с их правильной функциональностью.

Все фиаско, однако, заставило меня задуматься. Есть ли у них какие-либо общие рекомендации о том, когда не использовать несколько потоков и/или у кого-нибудь больше примеров ситуаций при использовании нескольких потоков, не является хорошей идеей?

** РЕДАКТИРОВАТЬ: Основываясь на ваших комментариях и после сокращения информации в Интернете, я написал сообщение в блоге под названием Когда многопоточность не очень хорошая идея?

4b9b3361

Ответ 1

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

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

Почему? Из-за аппаратных переключателей. Для аппаратного обеспечения требуется общее время для переключения между потоками. В многоядерном ящике, продолжайте использовать 1 поток для каждого ядра, и вы увидите, что вы увеличиваете скорость.

Ответ 2

Перефразировать старую цитату: у программиста была проблема. Он подумал: "Я знаю, я буду использовать темы". Теперь у программиста две проблемы. (Часто приписывается JWZ, но, похоже, предшествует его использованию, говоря о регулярных выражениях.)

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

Ответ 3

Многопоточность - это плохая идея, если:

  • Несколько потоков обращаются и обновляют один и тот же ресурс (устанавливают переменную, записывают в файл), и вы не понимаете безопасность потоков.

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

  • Ваша программа использует статические переменные (потоки обычно делят их по умолчанию).

  • Вы не отлаживали проблемы concurrency.

Ответ 4

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

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

Ответ 5

Возможно, вы захотите взглянуть на Дан Кегель "" Проблема C10K", посвященная обработке нескольких источников/стоков данных.

В основном лучше всего использовать минимальные потоки, которые в сокетах могут выполняться в большинстве ОС с некоторой системой событий (или асинхронно в Windows с использованием IOCP).

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

Пример схемы макета:

Per CPU [*] EVENTLOOP   ------ Handles nonblocking I/O using OS/library utilities
                       |                        \___  Threadpool for various blocking events
                       Threadpool for handling the I/O messages that would take long

Ответ 6

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

Ответ 7

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

Были продолжены дискуссии о том, следует ли рассматривать обработку каждого сообщения как задание, которое было передано потоку из пула потоков, но, в конце концов, это расширение, которое не стоило работать.

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

Ответ 8

Многопоточность плохое, за исключением одного случая, когда это хорошо. Этот случай

  • Работа связана с CPU Bound, или ее части связаны с ограничением по ЦП.
  • Работа параллелизуема.

Если одно или оба из этих условий отсутствуют, многопоточность не будет выигрышной стратегией.

Если работа не связана с ЦП, то вы не ожидаете окончания потоков для работы, а скорее для какого-либо внешнего события, такого как сетевая активность, чтобы процесс завершил свою работу. Используя потоки, есть дополнительная стоимость переключения контекста между потоками, стоимость синхронизации (мьютексы и т.д.) И неравномерность прерывания потока. Альтернативой в большинстве распространенных применений является асинхронный ввод-вывод, в котором один поток прослушивает несколько портов io и действует в зависимости от того, что будет сейчас готово, по одному за раз. Если случайно эти медленные каналы все-таки станут готовыми в одно и то же время, может показаться, что вы испытаете замедление, но на практике это редко бывает так. Стоимость обработки каждого порта по отдельности часто сопоставима или лучше, чем стоимость синхронизации состояния по нескольким потокам при опорожнении каждого канала.

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

Ответ 9

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

Ответ 10

Я бы сказал, что многопоточность обычно используется для:

  • Разрешить обработку данных в фоновом режиме, пока графический интерфейс остается отзывчивым.
  • Разделить очень большой анализ данных на несколько блоков обработки, чтобы вы могли быстрее получать результаты.
  • Когда вы получаете данные с какого-либо оборудования и нуждаетесь в чем-то, чтобы постоянно добавлять его в буфер, в то время как какой-то другой элемент решает, что с ним делать (писать на диск, отображать на графическом интерфейсе и т.д.).

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

Безопасность может быть причиной, чтобы избежать использования нескольких потоков (по нескольким процессам). См. Google chrome для примера возможностей многопроцессорной безопасности.

Ответ 11

Несколько возможных причин использования потоков:

  • На вашей платформе отсутствуют асинхронные операции ввода-вывода, например. Windows ME (нет портов завершения или перекрытия ввода-вывода, боль при переносе приложений XP, которые их используют.) Java 1.3 и ранее.
  • Функция сторонней библиотеки, которая может зависать, например. если удаленный сервер отключен, и библиотека не дает возможности отменить операцию, и вы не можете ее изменить.

Сохранение графического интерфейса, отвечающего при интенсивной обработке, не всегда требует дополнительных потоков. Обычно достаточно одной функции обратного вызова.

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

Ответ 12

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

Если вам не нужно многопоточность, это неверный вопрос к вашей проблеме. Ваша проблема заключается в следующем: почему многопоточность моего приложения вызвала связь между последовательными/Ethernet-соединениями?

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

Единственная причина не использовать многопоточность:

  • Существует одна задача, и нет интерфейса пользователя, с которым задача будет мешать.

Причины использования mutli-threading:

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

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

  • Thread Safe Типы данных, передаваемые между потоками.
  • Способы защиты потоков в потоковом объекте для изменения передаваемых данных.
  • Возможности PostMessage для связи между потоками.

Ответ 13

Являются ли процессы параллельными? Является ли работа реальной проблемой? Есть ли несколько "потоков" выполнения, например, на веб-сервере? Я не думаю, что есть конечный ответ.

Ответ 14

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