Re: Вопрос про потоки и как их организовать
От: ykurin  
Дата: 09.03.14 07:51
Оценка:
Здравствуйте, gamburger, Вы писали:

G>Для чего в приложении создавать более, чем 1 поток на одноядерном проце, более, чем 2 потока на двухядерном и т.д? Если потоков больше, чем ядер, они же все-равно будут выполняться не параллельно, а последовательно, так как ядро может выполнять только 1 поток, пока другие потоки будут ждать своей очереди? В чем выигрыш?


G>Мне нужно создать приложение на NET, которое бы работало под большой нагрузкой и принимало запросы от множества юзеров одновременно. Я прочитал, что для параллельного выполнения запросов нужно либо создавать для каждого запроса новый поток, либо юзать пул потоков. Сначала мне попадалась только инфа, будто бы пул потоков в NET — это крутая штука, которая будет грамотно распоряжаться потоками и нужно юзать ее. Но по мере дальнейшего чтения, мне стали попадаться сообщения, будто бы пул потоков при неаккуратном использовании может сделать что-то плохое с системой целиком (якобы этот пул общий для всей операционки, как я понял) и вообще, его опасно использовать. Что мне использовать в своем приложении, пул или создавать по новому потоку для каждого запроса, или еще что-нибудь?

G>Хотя, возвращаясь к своему первому абзацу, я реально не понимаю, как же на моем одноядерном проце последовательно выполняемые потоки могут ускорить обработку запросов юзеров.

G>Так же я помню, что в какой-то статье по этому пулу потоков в NET автор предлагал задавать максимальное число потоков для пула как 4 * Environment.ProcessorCount , то есть было написано "по 4 потока на 1 процессор (ядро)". Это правильно, чтобы задавать это значение от кол-ва ядер? Почему-то, я видел такое только в 1 статье, во всех остальных статьях по пулу макс. кол-во задавалось константой, например, 40. Откуда вообще там взяли это число — 40 , и опять — как 40 последовательно выполняющихся потоков на 1 ядре увеличивают производительность?


Добрый день.

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

1. Как уже здесь говорили, второй поток нужен для сохранения "отзывчивости" UI. Причем вы не можете сделать вторым потоком UI, так как все UI контролы (и в WPF и в WinForms) работаю в основном потоке приложения.
2. Второй случай — фоновые операции: проверка состояния (чего угодно), пинг, отправка данных, таймер и т.п. Это все делается асинхронно, в разных потоках.
3. Ваш случай, когда есть множество заказчиков (пользователей), которые посылают запросы серверу. Обычно для каждого запроса создается отдельный поток обработки. Это нужно для того, что бы заказчик понимал что его запрос принят. Если же вы ставите все в одну очередь, то при большом количестве запросов заказчики в конце очереди могут и не дождаться ответа (подумать что приложение или сервер не отвечают).
Понятно, что обработка запросов, скорее всего будет последовательная (если используются общие ресурсы, например БД), но первоначальный запрос должен обрабатываться асинхронно.

Схема такая:
1. В отдельном потоке №1 ждем запроса.
2. Получили запрос и запустили его обработку, ставим в очередь в поток №2.
3. В потоке №1 отправляем подтверждение, что запрос получен.
4. В потоке №2 обрабатывается запрос и отправляется результат заказчику.

Естественно, реальная архитектура может отличаться, в зависимости от кейсов.

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

Способов запуска метода в другом потоков множество:
1. Используя пул потоков ThreadPool.
2. Task (кстати, подходит для выстраивания очереди задач ContinueWith).
3. Асинхронный вызов: BeginInvoke
4. в C# 5 ключевые слова async и wait

Почитайте хотя бы статьи на этом сайте:
http://www.rsdn.ru/article/dotnet/CSThreading1.xml
Автор(ы): Joseph Albahari
Дата: 24.03.2007
Подробно рассматривается работа с потоками — запуск, завершение, прерывание, блокировки, синхронизация, контексты синхронизации, особенности взаимодействия с апартаментами, а также потоковые возможности .NET — потоковые таймеры, пулы потоков, BackgroundWorker, асинхронные методы и делегаты.
В статье использован материал из книги Joseph Albahari, Ben Albahari "C# 3.0 in a Nutshell" — http://www.oreilly.com/catalog/9780596527570/

http://www.rsdn.ru/article/dotnet/CSThreading2.xml
Автор(ы): Joseph Albahari
Дата: 27.06.2007
Окончание статьи, опубликованной в RSDN Magazine #1-2007. Рассматриваются особенности взаимодействия с апартаментами, потоковые таймеры, пулы потоков, BackgroundWorker, асинхронные методы и делегаты.
В статье использован материал из книги Joseph Albahari, Ben Albahari "C# 3.0 in a Nutshell" — http://www.oreilly.com/catalog/9780596527570/

http://www.rsdn.ru/article/dotnet/Threading_In_C_Sharp_Part_3.xml
Автор(ы): Joseph Albahari
Дата: 28.07.2011
В третьей части статьи рассматривается Parallel LINQ, класс Parallel, конструкции параллелизма задач, параллельные коллекции, а также структуры SpinLock и SpinWait. В статье использован материал из книги Joseph Albahari, Ben Albahari "C# 4.0 in a Nutshell" —  http://oreilly.com/catalog/9780596800963

http://www.rsdn.ru/article/csharp/Asynchronous_Programming_In_CSharp_5.xml
Автор(ы): Тепляков Сергей Владимирович
Дата: 05.02.2011
В статье рассматриваются новые возможности асинхронного программирования доступные в новой версии языка программирования C#.


Будут конкретные вопросы, задавайте.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.