ты путаешь программирование для каких-нибудь расчетов, там где тебе нужно максимально эффективно использовать ресурсы компа и обычные программы, которые, как правило, проектируются с точки зрения удобства разработки, поддержки, и чтобы у пользователя интерфейс по минимуму тормозил, тогда как в фоне идет работа с сетью, диском и прочими данными. Как раз ла2 является представителем второй категории, да и боту никогда не нужно столько расчетов, чтобы задумываться об эффективности использования каждого ядра и ручного распределения своих потоков между ядрами (у меня бот использует менее 1% от моего проца, и может его подгружать только при прорисовке карты, т.к. этот участок крайне не оптимален и медленный)
переменные на каждый поток:
общий_сетевой_буфер = массив байт равный максимальному размеру пакета (65535 в нашем случае)
боты = список ботов для обработки
тело_потока:
для каждого бота в ботах потока делаем:
{
бот.установить_буфер(общий_сетевой_буфер);
// в этом моменте бот использует общий буфер потока
// для приема и отправки данных
бот.получить_сетевые_данные_используя_буфер();
бот.послать_данные_используя_буфер();
бот.аннулировать_буфер();
// в этом моменте у бота больше нет буфера
// в следующей итерации общий буфер перейдет к следующему боту
}
Повторюсь, экономить потоки это хорошая идея. Но делать это надо не так. В том что ты предлагаешь следующие проблемы:
1) ручная балансировка ботов между потоками
2) прием данных бывает либо блокирующий, что в твоем случае не подходит. либо асинхронный. что в твоем случае не подходит. либо активное ожидание - привет дополнительные задержки и излишний расход процессорного времени.
И снова мы приходим к тому что код должен быть полностью асинхронный. А в асинхронном коде ограничение на неразрывность обработки одного пакета является злом. Вот захочу я посреди обработки пакета отправить пакет другому клиенту, в этот момент я должен отпустить поток исполняющий мой код, и прощайте буфера.
Yegor, если не вызывать WaitMessage то мессаджей ждать не придется, если ты об этом
Каким образом в асинхронном режиме ваш процесс узнает что пришла очередная порция данных в буфер, новое подключение и т.п.?
Вашему коду ждать не прийдется но месаг будет пойман и обработан в главном потоке ожидания месаджей, а это все задержки.
Yegor, хехе, я об этом подозревал, но не хотел вслух говорить.
но насколько долгие эти задержки? по хорошему надо затестить этот момент и сравнить с WSAPoll и с реализацией на блокирующих функциях (1 сокет = 2 потока). может быть это уже кем-нибудь было сделано?
Каким образом в асинхронном режиме ваш процесс узнает что пришла очередная порция данных в буфер, новое подключение и т.п.?
Вашему коду ждать не прийдется но месаг будет пойман и обработан в главном потоке ожидания месаджей, а это все задержки.
Скажу честно я не вникал как это работает в ядре Windows, я пишу на C#, внимательно изучил документацию и провел свои тесты.
Пусть это немного наивно, но вот что я сделал:
1) взял в аренду VDS, пропинговал его, получил пинг 59мс (да я знаю что пинг идет по ICMP)
2) написал свой сервер и свой клиент, подключился и дал 50mbps нагрузку по траффику через много копий клиента, сделал замеры времени ответа средствами языка, у меня снова получилось 59мс. 0% загрузка процессора, и ровно 4 потока в серверном приложении.
может быть задержки о которых вы говорите измеряются в наносекундах?) какая тогда разница