Этот вопрос является результатом двух других вопросов, которые я задавал в последние несколько дней.
Я создаю новый вопрос, потому что я думаю, что он связан со «следующим шагом» в моем понимании того, как контролировать поток моих отправки / получения, на который я еще не получил полного ответа.
Другие связанные вопросы:
Вопрос интерпретации документации IOCP - неопределенность владения буфером
Неблокирующие проблемы с буфером TCP
Итак, я использую порты завершения ввода / вывода Windows.
У меня есть несколько потоков, которые обрабатывают уведомления от порта завершения.
Я полагаю, что этот вопрос не зависит от платформы и будет иметь такой же ответ, как если бы он делал то же самое в системах * nix, * BSD, Solaris.
Итак, мне нужна собственная система управления потоком. Хорошо.
Так что я отправляю отправлять и отправлять, много. Как узнать, когда начинать ставить в очередь посылки, так как сторона получателя ограничена количеством X?
Давайте рассмотрим пример (наиболее близкий к моему вопросу): протокол FTP.
У меня есть два сервера; Один находится на ссылке 100 МБ, а другой на ссылке 10 МБ.
Я заказываю один 100 МБ, чтобы отправить другому (связанный 10 МБ) файл 1 ГБ. Он заканчивается со средней скоростью передачи 1,25 МБ / с.
Как отправитель (связанный со 100 МБ) знал, когда следует задержать отправку, чтобы более медленный не был затоплен? (В этом случае очередь «для отправки» является фактическим файлом на жестком диске).
Еще один способ задать вопрос:
Могу ли я получить уведомление о задержке отправки с удаленной стороны? Это встроенный в TCP или так называемый "надежный сетевой протокол", который мне нужен?
Конечно, я могу ограничить отправку фиксированным числом байтов, но это просто не подходит мне.
Опять же, у меня есть цикл с большим количеством отправок на удаленный сервер, и в какой-то момент в этом цикле я должен определить, должен ли я поставить эту очередь в очередь, или я могу передать ее на транспортный уровень (TCP) .
Как я могу это сделать? Чтобы ты делал? Конечно, когда я получу уведомление о завершении от IOCP о том, что отправка была выполнена, я отправлю другие ожидающие отправки, это ясно.
Еще один вопрос дизайна, связанный с этим:
Поскольку я должен использовать пользовательские буферы с очередью отправки, и эти буферы освобождаются для повторного использования (таким образом, не используя ключевое слово «delete»), когда получено уведомление «send-done», мне придется использовать взаимное исключение в этом пуле буферов.
Использование мьютекса замедляет работу, поэтому я подумал; Почему бы каждому потоку не иметь свой собственный пул буферов, поэтому доступ к нему, по крайней мере при получении необходимых буферов для операции отправки, не потребует мьютекса, поскольку он принадлежит только этому потоку.
Пул буферов находится на уровне локального хранилища потоков (TLS).
Отсутствие взаимного пула подразумевает отсутствие необходимости в блокировке, подразумевает более быстрые операции, НО также подразумевает больше памяти, используемой приложением, потому что даже если один поток уже выделил 1000 буферов, другому, который отправляет прямо сейчас и требуется 1000 буферов для отправки чего-либо, потребуется выделение это свое.
Другая проблема:
Скажем, у меня есть буферы A, B, C в очереди «для отправки».
Затем я получаю уведомление о завершении, в котором говорится, что получатель получил 10 из 15 байтов. Должен ли я повторно отправить из относительного смещения буфера, или TCP будет обрабатывать его для меня, т.е. завершить отправку? И если мне нужно, могу ли я быть уверен, что этот буфер является «следующим для отправки» в очереди или это может быть буфер B, например?
Это длинный вопрос, и я надеюсь, что никто не пострадал (:
Мне бы очень хотелось, чтобы кто-то нашел время, чтобы ответить здесь. Я обещаю, что дважды проголосую за него! (:
Спасибо всем!