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

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

Так же я помню, что в какой-то статье по этому пулу потоков в NET автор предлагал задавать максимальное число потоков для пула как 4 * Environment.ProcessorCount , то есть было написано "по 4 потока на 1 процессор (ядро)". Это правильно, чтобы задавать это значение от кол-ва ядер? Почему-то, я видел такое только в 1 статье, во всех остальных статьях по пулу макс. кол-во задавалось константой, например, 40. Откуда вообще там взяли это число — 40 , и опять — как 40 последовательно выполняющихся потоков на 1 ядре увеличивают производительность?
Re: Вопрос про потоки и как их организовать
От: xednay89 Россия  
Дата: 08.03.14 23:50
Оценка:
Здравствуйте, gamburger, Вы писали:

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


Например для того, чтобы легче было реализовать в приложении многозадачность.
Прим: приложение с UI должно выполнять долгие вычисления. Для того, чтобы UI не "замерзал" во время вычислений — можно реализовать многозадачность приложения через потоки. Хоть поток и будет один — задач приложение будет выполнять несколько одновременно(пользователю так будет казаться).

G>Что мне использовать в своем приложении, пул или создавать по новому потоку для каждого запроса, или еще что-нибудь?


смотря, что за приложение и что оно должно делать
Re: Вопрос про потоки и как их организовать
От: Shmj Ниоткуда  
Дата: 09.03.14 04:13
Оценка:
Здравствуйте, gamburger, Вы писали:

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


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

Второе. Поток не обязательно занимается операциями вычисления. Если поток в основном пишет на диск -- то нет смысла его распараллеливать, даже если 10 ядер, но диск в системе 1. Если же поток занимается сетевыми запросами -- то смысл в распареллеливании есть, причем прирост скорости будет вплоть до сотен потоков (процессор не задействован, ждем ответ по сети).
Re[2]: Вопрос про потоки и как их организовать
От: gamburger  
Дата: 09.03.14 06:52
Оценка:
Здравствуйте, xednay89, Вы писали:

X>Здравствуйте, gamburger, Вы писали:


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


X>Например для того, чтобы легче было реализовать в приложении многозадачность.

X>Прим: приложение с UI должно выполнять долгие вычисления. Для того, чтобы UI не "замерзал" во время вычислений — можно реализовать многозадачность приложения через потоки. Хоть поток и будет один — задач приложение будет выполнять несколько одновременно(пользователю так будет казаться).

G>>Что мне использовать в своем приложении, пул или создавать по новому потоку для каждого запроса, или еще что-нибудь?


X>смотря, что за приложение и что оно должно делать


Ну да, с UI-то мне понятно, как я понимаю, UI должен обновляться не реже , чем каждые 1/30 секунды, тут имеет смысл запускать каждые UI в отдельном потоке (так как UI легковесный и может быть быстро просчитан за нужное время), прерывая поток выполнения сложных расчетов (например, рендеринг), в рез-те рендеринг будет вычисляться дольше, но зато UI юудет отзывчивым.

Но зачем нужны еще потоки? Ну, может, если в процесс рендеринга в проге встроено музыкальное сопровождение, то , чтобы музыка не подвисала во время рендеринга, нужно ее, как и UI, выполнять в отдельном потоке.
На все это нужно, значит, 3 потока. Откуда во всяких туториалах берутся двухзначные числа потоков? Так как, как я понимаю, отдельные потоки нужны только для легковесных задач, которые должны отображаться в реальном времени (UI, воспроизведение музыки). Если, например, в разных потоках запустить 2 тяжеловесные задачи (2 рендеринга, которые , допустим, каждый по отдельности длится по минуте на моем компе), то из-за того, что потоки рендерингов будут прерывать друг друга, оба рендеринга будут готовы только через 2 минуты (тогда как, если запустить их последовательно, то первый выполнится через минуту, а другой, через 2).

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

Ну и вопрос, как узнать, сколько потоков выделить для веб-вервера выполнения? И нужно ли привязываться к переменной Environment.ProcessorCount ? И выделять ли потоков больше, чем Environment.ProcessorCount ? И через что лучше организовать потоки, через пул потоков или просто запускать новые потоки каждый раз при каждом запросе? Мне нужен высоконагруженный веб сервер, чтобы прогнать по нему тесты, симулирующие большой наплыв юзеров, но сервер работал, как положено.
Re[2]: Вопрос про потоки и как их организовать
От: B7_Ruslan  
Дата: 09.03.14 06:55
Оценка:
S>Второе. Поток не обязательно занимается операциями вычисления. Если поток в основном пишет на диск -- то нет смысла его распараллеливать, даже если 10 ядер, но диск в системе 1. Если же поток занимается сетевыми запросами -- то смысл в распареллеливании есть, причем прирост скорости будет вплоть до сотен потоков (процессор не задействован, ждем ответ по сети).

По моему в этом случае надо не самому создавать потоки, а использовать I/O Completion Ports через функции *Begin, *End
Re: Вопрос про потоки и как их организовать
От: smeeld  
Дата: 09.03.14 07:07
Оценка:
Здравствуйте, gamburger, Вы писали:

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


Много задач, с медленным выполнением каждой из них, зависящем от внешних условий, событий, IO процессов.
Последовательное выполнение каждой из задач в одном потоке будет медленнее, чем одновременное их исполнение в разных параллельно
исполняющихся потоках.
Re[2]: Вопрос про потоки и как их организовать
От: gamburger  
Дата: 09.03.14 07:42
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Здравствуйте, gamburger, Вы писали:


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


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

А почему он прирост скорости есть в случае с сетевыми запросами? Слушает запросы, как я понял из примеров, все-равно один поток, а обработчики запроса (коллбэки) выполняются уже в разных потоках. Но коллбеки же выполняется процессором, если запросов много, а проц (ядро) один, то процессор же не сможет выполнить запросы одновременно? Разделение на потоки создаст конкуренцию между потоками и оба запроса выполнятся даже позднее, чем последовательно (я описал , как я это понимаю, в ответе на предыдущее сообщение). Это не так, я не прав? Почему?

И еще вопрос, что происходит в момент вызова Thread.Sleep() с потоком? Он просто перестает выполняться, то есть, совсем не грузит проц? А поток-слушатель запросов, в момент когда он слушает запрос, как работает? По аналогии со Sleep , или он все-таки должен выполнять какую-то работу, то есть, он грузит проц?
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#.


Будут конкретные вопросы, задавайте.
Re[3]: Вопрос про потоки и как их организовать
От: ykurin  
Дата: 09.03.14 08:31
Оценка:
Здравствуйте, gamburger, Вы писали:

G>Здравствуйте, Shmj, Вы писали:


S>>Здравствуйте, gamburger, Вы писали:


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


G> Если же поток занимается сетевыми запросами -- то смысл в распареллеливании есть, причем прирост скорости будет вплоть до сотен потоков (процессор не задействован, ждем ответ по сети).


G>А почему он прирост скорости есть в случае с сетевыми запросами? Слушает запросы, как я понял из примеров, все-равно один поток, а обработчики запроса (коллбэки) выполняются уже в разных потоках. Но коллбеки же выполняется процессором, если запросов много, а проц (ядро) один, то процессор же не сможет выполнить запросы одновременно? Разделение на потоки создаст конкуренцию между потоками и оба запроса выполнятся даже позднее, чем последовательно (я описал , как я это понимаю, в ответе на предыдущее сообщение). Это не так, я не прав? Почему?


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


G>И еще вопрос, что происходит в момент вызова Thread.Sleep() с потоком? Он просто перестает выполняться, то есть, совсем не грузит проц? А поток-слушатель запросов, в момент когда он слушает запрос, как работает? По аналогии со Sleep , или он все-таки должен выполнять какую-то работу, то есть, он грузит проц?



Thread.Sleep процессор не загружает. Просто планировщик перестает выдавать квант процессорного времени указанному потоку.
Работа потока-слушателя зависит от того что от слушает. Он может ждать какого-нибудь event'а, в это случае он не занимает процессорное время. А может сам, периодически, опрашивать устройство, тогда процессор используется.
В случае сокетов, поток ожидания практически не использует процессор.
Re[4]: Вопрос про потоки и как их организовать
От: gamburger  
Дата: 09.03.14 09:06
Оценка:
G>>А почему он прирост скорости есть в случае с сетевыми запросами? Слушает запросы, как я понял из примеров, все-равно один поток, а обработчики запроса (коллбэки) выполняются уже в разных потоках. Но коллбеки же выполняется процессором, если запросов много, а проц (ядро) один, то процессор же не сможет выполнить запросы одновременно? Разделение на потоки создаст конкуренцию между потоками и оба запроса выполнятся даже позднее, чем последовательно (я описал , как я это понимаю, в ответе на предыдущее сообщение). Это не так, я не прав? Почему?

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



То есть, ускорение возможно, только если в системе более одного проца (чем больше, тем больше ускорение)? Это-то мне понятно, но тогда зачем выделять более 1 потока на проц, если ускорения не будет. А каким образом это поможет одновременным юзерам меньше ждать ответа сервера — мне не понятно.

Y>Асинхронность нужна, чтобы освободить поток-слушатель (вызов коллбэков).


Это как? Слушатель же, как только получит запрос, вызовет коллбек в другом потоке, а сам в своем потоке продолжит слушать другие запросы (то есть, он никогда не освобождается).
Re: Вопрос про потоки и как их организовать
От: Sharov Россия  
Дата: 09.03.14 09:43
Оценка:
Здравствуйте, gamburger, Вы писали:

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


Пул один для всего процесса. Представьте, что вы используете сторонние библиотеки, которые также работают с пулом.
Вся проблема в том, что вы исходили из того, что пул нужен только вам и конфигурировали его соотв. образом, а оказалось,
что пулом (и не понятно как) также пользуется сторонняя библиотека. Если код пишется с нуля, то тут все проще.
Кодом людям нужно помогать!
Re[5]: Вопрос про потоки и как их организовать
От: Sharov Россия  
Дата: 09.03.14 09:54
Оценка:
Здравствуйте, gamburger, Вы писали:

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


Слушатель ничего не слушает (извините за тавтологию). Поток регистрирует коллбэк и продолжает заниматься своими делами.
Приходят данные, коллбэк ставит себя в очередь на обработку в потоке. На все про все один поток.
Кодом людям нужно помогать!
Re: Вопрос про потоки и как их организовать
От: btn1  
Дата: 09.03.14 10:07
Оценка:
Здравствуйте, gamburger, Вы писали:

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


Всё просто: ресурсы, необходимые для обслуживания одного клиента, сильно меньше того, чем располагает компьютер. Скажем, каждому клиенту нужно 5% ЦПУ, 10Мег ОЗУ и пара чтений с диска. Но если у тебя одновременно обслуживается только один клиент, система тупо простаивает. Так что да, спокойно юзай пул — система сама разберётся, когда и чего создавать. Как вариант, есть "безтрэдовое" обслуживание, но тогда на тебя падает задача синхронизации (так работает nginx, например).
Re: Вопрос про потоки и как их организовать
От: Rinbe Россия  
Дата: 09.03.14 10:08
Оценка:
Здравствуйте, gamburger, Вы писали:

G>Мне нужно создать приложение на NET, которое бы работало под большой нагрузкой и принимало запросы от множества юзеров одновременно.


Нужно использовать многопоточность.

G>Я прочитал, что для параллельного выполнения запросов нужно либо создавать для каждого запроса новый поток, либо юзать пул потоков.


Как работает сервер на обычных потоках на практике если потоки при опереции ввода-вывода блокириются в ожидании данных. При 1000 подключений(1000 потоков) происходит следующее: сервер тормозит при подключении нового клиента, на это уходит около 15 секунд(видимо выделяется память при создании нового потока), происходят случайные непонятные скачки производительности. Если используется асинхронный ввод — вывод который использует пул потоков, сервер держит 30000 подключений без больших издержек.

Тут еще надо учитывать, что если потоки часто взаимодейстуют друг с другом через синхронизацию, а не только занимаются вводом-выводом, издержки тоже возрастают.
Re[5]: Вопрос про потоки и как их организовать
От: ykurin  
Дата: 09.03.14 11:39
Оценка:
Здравствуйте, gamburger, Вы писали:


G>>>А почему он прирост скорости есть в случае с сетевыми запросами? Слушает запросы, как я понял из примеров, все-равно один поток, а обработчики запроса (коллбэки) выполняются уже в разных потоках. Но коллбеки же выполняется процессором, если запросов много, а проц (ядро) один, то процессор же не сможет выполнить запросы одновременно? Разделение на потоки создаст конкуренцию между потоками и оба запроса выполнятся даже позднее, чем последовательно (я описал , как я это понимаю, в ответе на предыдущее сообщение). Это не так, я не прав? Почему?


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



G>То есть, ускорение возможно, только если в системе более одного проца (чем больше, тем больше ускорение)? Это-то мне понятно, но тогда зачем выделять более 1 потока на проц, если ускорения не будет. А каким образом это поможет одновременным юзерам меньше ждать ответа сервера — мне не понятно.


Вы не поняли меня. Пользователь не получит ответ на запрос быстрее, только потому что вы использовали несколько потоков.

У нас есть такая конфигурация:
1. Есть БД с которой работают удаленные пользователи (естественно, не на прямую, а посредством сайта, например).
2. В основном, пользователи читают информацию. Хотя некоторые могут и изменять ее.
3. Основное и большое количество запросов именно на чтение.
4. Читать из БД могут несколько пользователей сразу.

1-й вариант.
Мы все запросы ставим в очередь в один поток.

Тогда время выполнения запроса пользователя N а очереди равно сумме времени выполнения всех запросов перед ним + время его собственного запроса.

2-й вариант
Все запросы выполняются параллельно (БД это позволяет).

В этом случае, если процессор слабый, БД плохо оптимизирована и т.п. мы получим последовательное выполнение всех запросов, как и в варианте 1.
Это худший случай и мы ничего не выиграем.

Но это маловероятно, так как одни запрос не всегда занимает 100% процессорного времени. И выигрыш все-таки будет, а вот какой — сказать сложно, не зная деталей.

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

Y>>Асинхронность нужна, чтобы освободить поток-слушатель (вызов коллбэков).


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



А вы попробуйте более детально объяснить что вам конкретно нужно и что вас смущает.

Вопрос в том, что получив асинхронное уведомление о запросе вы не обрабатываете его прямо в коллбэке, а ставите в очередь другого потока?
Re[3]: Вопрос про потоки и как их организовать
От: Shmj Ниоткуда  
Дата: 09.03.14 20:06
Оценка:
Здравствуйте, B7_Ruslan, Вы писали:

B_R>По моему в этом случае надо не самому создавать потоки, а использовать I/O Completion Ports через функции *Begin, *End


Чем лучше? Удобнее использовать новый механизм async/await. Но по сути дело только в синтаксисе, разницы абсолютно никакой.
Re[3]: Вопрос про потоки и как их организовать
От: Shmj Ниоткуда  
Дата: 09.03.14 20:08
Оценка:
Здравствуйте, gamburger, Вы писали:

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


А вы представьте вам нужно сделать краулер, который одновременно будет скачивать (ожидать ответа) от тысяч серверов. Как вы это сделаете?

G>Это не так, я не прав? Почему?


G>И еще вопрос, что происходит в момент вызова Thread.Sleep() с потоком? Он просто перестает выполняться, то есть, совсем не грузит проц? А поток-слушатель запросов, в момент когда он слушает запрос, как работает? По аналогии со Sleep , или он все-таки должен выполнять какую-то работу, то есть, он грузит проц?


Так запустите проверьте. Конечно не грузит.
Re[4]: Вопрос про потоки и как их организовать
От: xednay89 Россия  
Дата: 09.03.14 21:39
Оценка:
Здравствуйте, Shmj, Вы писали:
S>прирост скорости будет вплоть до сотен потоков (процессор не задействован, ждем ответ по сети).

S>Чем лучше? Удобнее использовать новый механизм async/await. Но по сути дело только в синтаксисе, разницы абсолютно никакой.


Тем, что не будет "ждущих" потоков. Сто потоков — около 100 дополнительно съеденных мегабайт памяти, плюс накладные расходы.

Так что разница еще какая.
Re[5]: Вопрос про потоки и как их организовать
От: Sinix  
Дата: 11.03.14 08:42
Оценка:
Здравствуйте, xednay89, Вы писали:

S>>Чем лучше? Удобнее использовать новый механизм async/await. Но по сути дело только в синтаксисе, разницы абсолютно никакой.

X>Тем, что не будет "ждущих" потоков. Сто потоков — около 100 дополнительно съеденных мегабайт памяти, плюс накладные расходы.

Так async/await наворачивается поверх чего угодно, в том числе и поверх IOCP (даже если забыть про таски — ThreadPool держит отдельный пул под async io). Накладные расходы от самих тасков стремятся к нулю, так что 100 мб памяти тут не будет.
Re[2]: Вопрос про потоки и как их организовать
От: gamburger  
Дата: 15.03.14 18:00
Оценка:
Здравствуйте, btn1, Вы писали:

B>Здравствуйте, gamburger, Вы писали:


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


B>Всё просто: ресурсы, необходимые для обслуживания одного клиента, сильно меньше того, чем располагает компьютер. Скажем, каждому клиенту нужно 5% ЦПУ, 10Мег ОЗУ и пара чтений с диска. Но если у тебя одновременно обслуживается только один клиент, система тупо простаивает. Так что да, спокойно юзай пул — система сама разберётся, когда и чего создавать. Как вариант, есть "безтрэдовое" обслуживание, но тогда на тебя падает задача синхронизации (так работает nginx, например).


А вот это мне интересно — как для одного клиента (запроса) может быть нужно 5% цпу, а не 100% ? Ведь если на 1 ядре может выполняться одновременно только 1 поток, то проц должен выполнять его максимально эффективно, то есть используя на 100% свои ресурсы.
А пример с памятью тут не особо подходящий или мне просто так кажется? Кол-во памяти не влияет на скорость выполнения потока, поэтому если поток юзает ее на 1% , то , запустив 100 потоков , мы заюзаем память на 100%, но толку от этого не будет, так как проц все равно должен обрабатывать 100 потоков в 100 раз медленее , чем 1 поток.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.