2017-02-15 19 views

ответ

3

Это будет иметь значение для отправки. (Я предполагаю, что вы используете сокет TCP для целей этой дискуссии.)

При попытке отправить 1K ядро ​​будет принимать этот 1K, скопировать его в ядро ​​TCP-буферы и вернуть успех (и, возможно, начать отправку к сверстнику в то же время). В этот момент вы отправите еще 1K, и произойдет то же самое. В конце концов, если файл достаточно велик, и сеть не может отправить его достаточно быстро или приемник не сможет его слить достаточно быстро, пространство буфера ядра, используемое вашими данными, достигнет некоторого внутреннего предела, и ваш процесс будет заблокирован до тех пор, пока приемник истощает достаточное количество данных. (Это ограничение часто может быть довольно высоким при использовании TCP - в зависимости от ОС, вы можете отправить мегабайт или два, не нажимая его.)

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

Однако с помощью первого механизма вы можете отправить файл любого размера без использования неоправданных объемов памяти - ваш буфер в памяти (не включая буферы TCP ядра) должен быть длиной 1 КБ. С sendall подход file.read() прочитает весь файл в памяти вашей программы. Если вы попытаетесь сделать это с действительно гигантским файлом (скажем, 40G или что-то еще), это может занять больше памяти, чем у вас, даже включая пространство подкачки.

Итак, в качестве механизма общего назначения я бы определенно поддержал первый подход. Однако для современных архитектур я бы использовал более крупный размер буфера, чем 1K. Точное число, вероятно, не слишком критично; но вы можете выбрать что-то, что поместит сразу несколько блоков диска, скажем, 256K.

+0

И какой размер прочтений вы бы предложили на принимающей стороне? – RomaValcer

+0

Такой же общий подход: я бы использовал достаточно большой, но не огромный буфер (64K или 256K). Из-за того, как работает TCP, вы можете получить буферы, которые только частично заполнены. Но просто добавьте каждый кусок, полученный напрямую в файл. (Ядро уже имеет хорошо оптимизированный код для агрегирования последовательно написанных буферов, а добавление буферов на питоне просто приводит к ненужным дополнительным копиям памяти.) –

 Смежные вопросы

  • Нет связанных вопросов^_^