Когда следует использовать потоки?
Насколько мне известно, идеальное количество потоков составляет 3: один для пользовательского интерфейса, один для ресурсов процессора и один для ресурсов ввода-вывода.
Но я, вероятно, ошибаюсь.
Я просто познакомился с ними, но я всегда использовал его для интерфейса и для всего остального.
Когда я должен использовать потоки и как? Как узнать, должен ли я их использовать?
Ответы
Ответ 1
К сожалению, нет жестких и быстрых правил использования Threads. Если у вас слишком много потоков, процессор будет тратить все свое время на создание и переключение между ними. Используйте слишком мало потоков, вы не получите требуемую пропускную способность в своем приложении. Кроме того, использование потоков нелегко. Язык, подобный С#, упрощает работу с вами, потому что у вас есть такие инструменты, как ThreadPool.QueueUserWorkItem
. Это позволяет системе управлять созданием и уничтожением потоков. Это помогает смягчить накладные расходы на создание нового потока для передачи работы. Вы должны помнить, что создание потока - это не операция, которую вы получаете за "свободный". Существуют затраты, связанные с запуском потока, поэтому его всегда следует принимать во внимание.
В зависимости от языка, который вы используете для написания приложения, вы будете определять, сколько вам нужно беспокоиться об использовании потоков.
Время, которое я чаще всего нахожу в том, что мне нужно явно создавать потоки, следующее:
- Асинхронные операции
- Операции, которые могут быть распараллелены
- Непрерывные фоновые операции
Ответ 2
Ответ полностью зависит от того, что вы планируете делать. Тем не менее, один для ресурсов ЦП - это плохой ход - у вашего процессора может быть до шести ядер, плюс гиперпоточность, в розничном процессоре, а у большинства процессоров будет два или более. В этом случае у вас должно быть столько потоков, сколько ядер процессора, плюс еще несколько для планирования неудач. Весь процессор не является однопоточным зверем, он может иметь много ядер и требует много потоков для 100% использования.
Вы должны использовать потоки тогда и только тогда, когда ваша целевая демография будет иметь практически все многоядерные (как в случае с текущими рынками настольных компьютеров и ноутбуков), и вы определили, что одного ядра недостаточно.
Ответ 3
Из SQLite FAQ: " Темы являются злыми Избегайте их. " Используйте их только тогда, когда вам абсолютно необходимо.
Если вам нужно, то предпринимайте шаги, чтобы избежать обычной бойни. Используйте пулы потоков для выполнения мелкомасштабных задач без взаимозависимостей, используя средства, предоставленные графическим интерфейсом, для отправки результатов обратно в пользовательский интерфейс. Избегайте совместного использования данных между длинными потоками; использовать очереди сообщений для передачи информации между ними (и для синхронизации).
Более экзотическим решением является использование таких языков, как Erlang, которые явно предназначены для мелкозернистого parallelism, не жертвуя безопасностью и понятностью. Concurrency сам имеет фундаментальное значение для будущего вычисления; потоки - это просто ужасный, сломанный способ выразить это.
Ответ 4
Херб Саттер написал статью для журнала Dr. Dobb Journal, в которой он рассказывает о трех столпах concurrency. В этой статье очень неплохо было бы решить, какие проблемы являются хорошими кандидатами для решения с помощью конструкторов потоковой передачи.
Ответ 5
"Идеальное количество потоков" зависит от вашей конкретной проблемы и количества parallelism, которую вы можете использовать. Если у вас есть проблема, которая является "смущающей параллелью" в том смысле, что ее можно подразделить на независимые проблемы, при которой между ними не требуется никакой связи, и у вас достаточно ядер, которые вы действительно можете получить true parallelism, то сколько потоков вы используете зависит от таких вещей, как размер проблемы, размер строки кэша, переключение контекста и нереста, а также различные другие вещи, которые очень сложно вычислить перед началом работы. Для таких ситуаций вам действительно нужно сделать некоторые профилирования, чтобы выбрать оптимальное очертание/разбиение вашей проблемы по потокам. Однако, как правило, не имеет смысла использовать больше потоков, чем вы делаете ядра. Верно также, что если у вас много синхронизации, то на самом деле у вас может быть ограничение производительности для использования потоков. Он сильно зависит от конкретной проблемы, а также от того, насколько взаимозависимы различные этапы. В качестве руководящего принципа вам необходимо знать, что нерестовые потоки и синхронизация потоков являются дорогостоящими операциями, но параллельное выполнение вычислений может увеличить пропускную способность, если связь и другие формы синхронизации минимальны. Вы также должны знать, что потоковая передача может привести к очень плохой производительности кеша, если ваши потоки в конечном итоге аннулируют обоюдную линию кэша.