Неблокирующая млок ()

0

Существует ли такая вещь, как неблокирующий mlock()? В условиях интенсивного трафика я не хочу, чтобы мои потоки блокировали ожидания ввода-вывода. Я хотел бы просто сказать ядру Linux, какой регион мне нужен из файла mmap() 'd, используя mlock(), и затем получать уведомление, когда страницы были извлечены. (Насколько я знаю, стандартный вызов mlock() блокируется.)

Теги:
file-io

3 ответа

2

Я считаю, что вам нужна комбинация madvise() или posix_madvise() и mincore().

Вы должны использовать madvise call, чтобы спросить ядро для MADV_WILLNEED. Затем вам нужно будет опросить, используя mincore чтобы проверить, были ли страницы прочитаны в памяти.

Если система находится под большой нагрузкой на память, страницы могут никогда не читаться при вызове madvise, поэтому вам потребуется тайм-аут и возврат к режиму блокировки чтения.

  • 1
    +1 Я бы даже сказал, madvise один только madvise - лучший путь, и все без mincore . Предоставление ОС нескольких миллиардных стартовых мощностей для загрузки страниц должно работать большую часть времени, и если она этого не делает, вы в любом случае в растерянности (в таком случае может произойти и сбой страницы, такой же эффект действительно). MADV_NORMAL только помнить, чтобы сбрасывать страницы до MADV_NORMAL после этого, или через некоторое время ваше полное адресное пространство будет установлено как «потребуется», и оно станет бесполезным.
  • 0
    @ Damon: Но это относится к mlock, который является своего рода «потребностью». Кроме того, я уверен, что после загрузки страницы в оперативную память ядро Linux игнорирует / сбрасывает флаг WILLNEED. Я не уверен, верно ли это для всех систем POSIX.
2

Интерфейс mlock, похоже, не имеет встроенных функций, как то, что вы хотите, поэтому я думаю, что единственный способ добиться этого - использовать отдельный поток для выполнения mlock и сообщить этому потоку (через переменную условия, семафор, или другой механизм), когда mlock вернулся. Очевидно, что это повлечет за собой некоторые накладные расходы, но если ваша цель состоит в том, чтобы получить гарантии времени в реальном времени, а не улучшать общую продолжительность выполнения/среднюю задержку, это все равно очевидная победа.

Конечно, трудно сделать какие-либо предположения в реальном времени, если вы не используете mlockall так как ваш код может быть заменен. Таким образом, имеет смысл использовать mlockall и POSIX AIO (или аналогичную, но более чистую API-систему, реализованную с точки зрения потоков) для чтения, а не для использования mmap. Тогда у вас есть твердая гарантия, что, как только ваши данные будут извлечены, его нельзя будет поменять.

0

Если вы mmap() файл, то вы обрабатываете файл как память, файлы страниц VM в/из файлов в зависимости от вашего использования, которые могут быть полезны для чтения вперед.

Существуют различные способы делать неблокирующие операции ввода-вывода (asyncio, poll, select, epoll), но mlock() - это сохранение области памяти в ОЗУ, не позволяющая ее выгружать в раздел подкачки; хотя под серьезным давлением памяти ядро может не соблюдать это.

Скорее всего, mmap (2) будет достаточно, как если бы вы использовали страницы памяти, они не будут выбраны для выхода из страницы, но все равно сохраняются в памяти, поэтому подумайте, является ли этот вопрос преждевременной оптомизацией, ядро пытается выполнить (по умолчанию ) хорошая производительность.

  • 0
    mlock'd память никогда не пойдет на обмен. Машина врезается первой. Это одна из причин, по которой ограничено количество заблокированных учетных записей.
  • 0
    Согласно недавней статье LWN.net, это не совсем верно, если давление памяти достаточно высокое, ядро может игнорировать «запрос», хотя есть способ mlock, который гарантирует, что заблокированный регион никогда не будет выбран, независимо от того, насколько отчаянно работает ядро. получает, что требует вызовов по умолчанию.
Показать ещё 6 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню