Как сделать приложение многопоточным? Вы используете асинхронные функции? или вы создаете новую ветку? Я думаю, что асинхронные функции уже порождают поток, поэтому, если ваша работа просто читает файл, ленив и просто порождает свою работу в потоке, вы просто «тратите» ресурсы ... Так есть ли какой-то дизайн при использовании потоковых или асинхронных функций?





Если вы говорите о .Net, не забудьте про ThreadPool. Пул потоков - это также то, что часто используют асинхронные функции. Создание большого количества потоков может на самом деле снизить вашу производительность. Пул потоков предназначен для создания достаточного количества потоков для максимально быстрого выполнения работы. Поэтому используйте пул потоков вместо того, чтобы создавать собственные потоки, если только пул потоков не соответствует вашим потребностям.
PS: И следите за Параллельные расширения от Microsoft
Использование потоков заставляет вас больше думать о том, как вашему приложению требуется многопоточность, и может в конечном итоге упростить улучшение / управление вашей производительностью. Асинхронные методы быстрее в использовании, но они немного волшебны - многие вещи делают их возможными - поэтому вполне вероятно, что в какой-то момент вам понадобится что-то, что они не могут вам дать. Затем вы можете попробовать накрутить какой-нибудь собственный код потоковой передачи. Все зависит от ваших потребностей.
Создание потоков будет тратить ресурсы только в том случае, если вы начнете создавать их тонны, один или два дополнительных потока не повлияют на проработку платформ, на самом деле System в настоящее время имеет более 70 потоков для меня, а msn использует 32 (у меня действительно есть Понятия не имею, как мессенджер может использовать такое количество потоков, особенно когда он свернут и на самом деле ничего не делает ...)
Обычно хорошее время для создания потока - это когда что-то занимает много времени, но вам нужно продолжать делать что-то еще.
например, расчет займет 30 секунд. Лучше всего создать новый поток для расчета, чтобы вы могли продолжать обновлять экран и обрабатывать любой ввод пользователя, потому что пользователи будут ненавидеть его, если ваше приложение зависает до тех пор, пока оно не закончит выполнение расчета.
С другой стороны, создание потоков для выполнения чего-то, что можно сделать почти мгновенно, почти бессмысленно, поскольку накладные расходы на создание (или даже просто передачу работы существующему потоку с использованием пула потоков) будут выше, чем просто выполнение работы в первое место.
Иногда вы можете разбить свое приложение на несколько отдельных частей, которые работают в своих собственных потоках. Например, в играх обновления / физика и т. д. Могут быть одним потоком, в то время как графика - другим, звук / музыка - третьим, а сеть - другим. Проблема здесь в том, что вам действительно нужно подумать о том, как эти части будут взаимодействовать, иначе у вас может быть худшая проработка, ошибки, которые появляются на первый взгляд «случайным образом», или даже может возникнуть тупик.
Я второй ответ Fire Lancer's - создание собственных потоков - отличный способ обрабатывать большие задачи или обрабатывать задачу, которая в противном случае была бы «блокирована» для остальной части синхронного приложения, но, вы должны иметь четкое представление о проблеме, которая вы должны решать и развиваться таким образом, чтобы четко определить задачу потока и ограничить объем того, что он делает.
В качестве примера, над которым я недавно работал, - консольное приложение Java запускается периодически для сбора данных, по сути, путем считывания URL-адресов с экрана, анализа документа с помощью DOM, извлечения данных и сохранения их в базе данных.
Как однопоточное приложение, оно, как и следовало ожидать, занимало возраст, в среднем около 1 URL-адреса в секунду для страницы размером 50 КБ. Неплохо, но когда вы увеличиваете масштаб до необходимости обрабатывать тысячи URL-адресов в пакете, это бесполезно.
Профилирование приложения показало, что большую часть времени активный поток простаивал - он ждал операций ввода-вывода - открытия сокета для удаленного URL-адреса, открытия соединения с базой данных и т. д. улучшено с многопоточностью. Перезапись на многопоточность и использование всего 5 потоков вместо одного, даже на одноядерном процессоре, увеличила пропускную способность более чем в 20 раз.
В этом примере каждый «рабочий» поток был явно ограничен тем, что он делал - открывал удаленный URL-адрес, анализировал данные, сохранял их в базе данных. Вся «высокоуровневая» обработка - создание списка URL-адресов для анализа, определение следующих, обработка ошибок - все оставалось под контролем основного потока.
Ответ - «это зависит от обстоятельств».
Это зависит от того, чего вы пытаетесь достичь. Я предполагаю, что вы стремитесь к большей производительности.
Самое простое решение - найти другой способ улучшить свою производительность. Запустите профилировщик. Ищите горячие точки. Уменьшите ненужный ввод-вывод.
Следующее решение - разбить вашу программу на несколько процессов, каждый из которых может работать в собственном адресном пространстве. Это проще всего, потому что нет шансов, что отдельные процессы испортят друг друга.
Следующее решение - использовать потоки. На этом этапе вы открываете большую банку червей, поэтому начните с малого и используйте только многопоточность для критического пути кода.
Следующее решение - использовать асинхронный ввод-вывод. Обычно рекомендуется только для людей, пишущих некоторые из очень сильно загруженных серверов, и даже тогда я бы предпочел повторно использовать одну из существующих фреймворков, которые абстрагируются от деталей, например. фреймворк C++ ICE или сервер EJB под java.
Обратите внимание, что каждое из этих решений имеет несколько дополнительных решений - существуют разные виды потоков и разные виды асинхронного ввода-вывода, каждый с немного разными характеристиками производительности, но, опять же, обычно лучше позволить фреймворку справиться с этим за вас.