Существует ли такая вещь, как неблокирующий mlock()? В условиях интенсивного трафика я не хочу, чтобы мои потоки блокировали ожидания ввода-вывода. Я хотел бы просто сказать ядру Linux, какой регион мне нужен из файла mmap() 'd, используя mlock(), и затем получать уведомление, когда страницы были извлечены. (Насколько я знаю, стандартный вызов mlock() блокируется.)
Я считаю, что вам нужна комбинация madvise()
или posix_madvise()
и mincore()
.
Вы должны использовать madvise
call, чтобы спросить ядро для MADV_WILLNEED
. Затем вам нужно будет опросить, используя mincore
чтобы проверить, были ли страницы прочитаны в памяти.
Если система находится под большой нагрузкой на память, страницы могут никогда не читаться при вызове madvise
, поэтому вам потребуется тайм-аут и возврат к режиму блокировки чтения.
Интерфейс mlock
, похоже, не имеет встроенных функций, как то, что вы хотите, поэтому я думаю, что единственный способ добиться этого - использовать отдельный поток для выполнения mlock
и сообщить этому потоку (через переменную условия, семафор, или другой механизм), когда mlock
вернулся. Очевидно, что это повлечет за собой некоторые накладные расходы, но если ваша цель состоит в том, чтобы получить гарантии времени в реальном времени, а не улучшать общую продолжительность выполнения/среднюю задержку, это все равно очевидная победа.
Конечно, трудно сделать какие-либо предположения в реальном времени, если вы не используете mlockall
так как ваш код может быть заменен. Таким образом, имеет смысл использовать mlockall
и POSIX AIO (или аналогичную, но более чистую API-систему, реализованную с точки зрения потоков) для чтения, а не для использования mmap
. Тогда у вас есть твердая гарантия, что, как только ваши данные будут извлечены, его нельзя будет поменять.
Если вы mmap() файл, то вы обрабатываете файл как память, файлы страниц VM в/из файлов в зависимости от вашего использования, которые могут быть полезны для чтения вперед.
Существуют различные способы делать неблокирующие операции ввода-вывода (asyncio, poll, select, epoll), но mlock() - это сохранение области памяти в ОЗУ, не позволяющая ее выгружать в раздел подкачки; хотя под серьезным давлением памяти ядро может не соблюдать это.
Скорее всего, mmap (2) будет достаточно, как если бы вы использовали страницы памяти, они не будут выбраны для выхода из страницы, но все равно сохраняются в памяти, поэтому подумайте, является ли этот вопрос преждевременной оптомизацией, ядро пытается выполнить (по умолчанию ) хорошая производительность.
madvise
один толькоmadvise
- лучший путь, и все безmincore
. Предоставление ОС нескольких миллиардных стартовых мощностей для загрузки страниц должно работать большую часть времени, и если она этого не делает, вы в любом случае в растерянности (в таком случае может произойти и сбой страницы, такой же эффект действительно).MADV_NORMAL
только помнить, чтобы сбрасывать страницы доMADV_NORMAL
после этого, или через некоторое время ваше полное адресное пространство будет установлено как «потребуется», и оно станет бесполезным.