Может ли [
blockquote>BlockingIOError
в асинхронном ридере] вообще никогда не происходить, логически? Если это возможно, то при каких обстоятельствах?Ответ на этот вопрос почти наверняка будет зависеть от системы. Сам Python не дает никаких гарантий по этому вопросу: такие функции, как
os.read
иsocket.recv
, просто проверяют значение, возвращаемое базовым системным вызовом, и, если это указывает на ошибку, продолжают преобразовывать системную ошибку в Исключение Python.Таким образом, вопрос сводится к тому, может ли чтение из сокета потерпеть неудачу с
EAGAIN
или эквивалентным, если предыдущий опрос / выбор показал, что он был читаем (и эквивалент для записи). Хотя это, безусловно, звучит как ненормальная ситуация, справочная страницаselect(2)
явно предупреждает об этом в BUGS:В Linux
blockquote>select()
может сообщить дескриптор файла сокета как «готовый к чтению», но, тем не менее, последующие блоки чтения. Это может, например, произойти, когда данные поступили, но при проверке они имеют неверную контрольную сумму и отбрасываются. Могут быть другие обстоятельства, при которых файловый дескриптор ложно сообщается как готовый. Поэтому может быть безопаснее использоватьO_NONBLOCK
на сокетах, которые не должны блокироваться.В случае неблокирующих сокетов следует читать «тем не менее последующие блоки чтения» как «тем не менее последующее чтение завершается неудачно с
EAGAIN
», и предупреждение относится к этому вопросу. Эта проблема также не относится кselect()
; Страница руководстваpoll(2)
также упоминает о ложных пробуждениях в разделе ошибок, обращаясь к руководствуselect(2)
за подробностями.Другими словами, переносимый код не должен полагаться на чтение из «читаемых» сокетов, которые никогда не поднимаются
BlockingIOError
. Asyncio не полагается на него: он реагирует наEAGAIN
просто , не завершая будущее , и, таким образом, повторно приостанавливает сопрограмму, ожидающую чтения.
Послушайте: http://www.xml.com/ldd/chapter/book/ch13.html
Ядро низкая память является 'реальной' картой распределения памяти, обращенной с 32-разрядными указателями на x86.
Верхняя память ядра является 'виртуальной' картой распределения памяти, обращенной с виртуальными структурами на x86.
Вы не хотите отображать все это в адресное пространство ядра, потому что Вы не можете всегда обращаться ко всему этому, и Вам нужна большая часть Вашей памяти для сегментов виртуальной памяти (виртуальное, отображенное на страницу пространство процесса.)
По крайней мере, это - то, как я считал его. Ничего себе, это - сложный вопрос, который Вы задали.
Для броска большего количества беспорядка глава 13 говорит о некоторых устройствах PCI, не бывших способных обратиться к 32-разрядному пространству, которое было происхождением моего предыдущего комментария:
На x86 некоторое использование памяти ядра ограничено первым Гигабайтом памяти, потому что из DMA обращение касается. Я не на 100% знаком с темой, но существует comapatibility режим для DMA на шине PCI. Это может быть тем, на что Вы смотрите.
3.6 ГБ не является потолком при использовании расширения физического адреса, которое обычно необходимо на большинстве современных x86 плат, особенно с заменой в горячем режиме памяти.