У меня небольшая проблема с подкачкой в моей системе реального времени, и я хотел знать, как именно 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 (). И если это так, то блокировка их в обоих потоках (но не в основном) будет правильной процедурой.