Являются ли заблокированные страницы унаследованными от pthreads? - PullRequest
2 голосов
/ 24 мая 2019

У меня небольшая проблема с подкачкой в ​​моей системе реального времени, и я хотел знать, как именно Linux должен вести себя в моем конкретном случае.

Помимо прочего, мое приложение порождает 2 потока, используя pthread_create (), которые работают с набором общих буферов. Первый поток, назовем его A, считывает данные с устройства, выполняет некоторые вычисления и записывает результаты в один из буферов. После заполнения этого буфера поток B будет считывать все результаты и отправлять их на ПК через Ethernet, а поток A записывает в следующий буфер.

Я заметил, что каждый раз, когда поток A начинает запись в ранее неиспользуемый буфер, я пропускаю некоторые прерывания и теряю данные (в заголовке каждого пакета есть идентификатор, и если он увеличивается более чем на один, я пропустил перебивает). Поэтому, если я использую n буферов, я получаю ровно n пакетов пропущенных прерываний в начале сбора данных (поэтому проблема определенно вызвана поиском по страницам).

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

Согласно документации libc (раздел 3.4.2 «Сведения о заблокированной памяти») блокировки памяти не наследуются дочерними процессами, созданными с использованием fork (). Так что насчет pthreads? Они ведут себя одинаково или наследуют эти блокировки от моего основного процесса?

Некоторая справочная информация о моей системе, хотя я не думаю, что это имеет значение в данном конкретном случае:

  • Это встроенная система на базе SoC с двухъядерным процессором Cortex-A9 под управлением Linux 4.1.22 с PREEMPT_RT.
  • Частота прерывания 4 кГц
  • Приоритеты потока (как показано в htop) составляют -99 для прерывания, -98 для потока A (оба из которых выше стандартного приоритета -51 для всех остальных прерываний) и -2 для потока B

EDIT:

Я провел несколько дополнительных тестов, вызывая функцию блокировки страницы из разных потоков (и в основном).

Если я заблокирую страницы в main (), а затем попытаюсь снова заблокировать их в одном из потоков, я ожидаю увидеть большое количество сбоев страниц для main (), но никаких сбоев страниц для самого потока ( потому что страницы уже должны быть заблокированы). Однако htop рассказывает другую историю: я вижу большое количество сбоев страниц (столбец MINFLT) для каждого потока, который блокирует эти страницы.

Для меня это говорит о том, что pthread действительно имеет то же ограничение, что и дочерние процессы, порожденные с помощью fork (). И если это так, то блокировка их в обоих потоках (но не в основном) будет правильной процедурой.

1 Ответ

1 голос
/ 24 мая 2019

Потоки используют один и тот же контекст управления памятью.Если страница является резидентной для одного потока, она является резидентной для всех потоков в одном и том же процессе.

Это означает, что блокировка памяти для каждого процесса, а не для потока.

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

...