Я работаю на платформе под управлением MontaVista Linux 3.1.
У меня есть приложение C ++, которое по эзотерическим причинам, в которые я не буду вдаваться, должно регулярно перемонтировать файловую систему флеш-памяти JFFS2 между режимами «только чтение» и «чтение и запись».
Когда вы выполняете int mount(...)
вызов, указанный в sys/mount.h
, чтобы установить файловую систему для чтения-записи, jffs2_gcd_mtd0
процесс сборки мусора запускается, как и следовало ожидать. Тем не менее, когда вы повторяете mount
позвонить, чтобы вернуться в режим только для чтения, jffs2_gcd_mtd0
убивается и становится несуществующим процессом.
Через несколько минут мы в конечном итоге с грузом перестал jffs2_gcd_mtd0
процессы, которые независимо от того, что мы делаем, мы не можем избавиться.
Я могу повторить проблему с помощью следующего тестового приложения:
int main()
{
while(true)
{
mount("/dev/mtdblock/0", "flash", "", MS_REMOUNT|MS_POSIXACL|MS_ACTIVE|MS_NOUSER|0XEC0000, "");
sleep(1);
mount("/dev/mtdblock/0", "flash", "", MS_RDONLY|MS_REMOUNT|MS_POSIXACL|MS_ACTIVE|MS_NOUSER|0XEC0000, "");
sleep(1);
}
}
Я пробовал различные способы пожинать несуществующие процессы: установка signal(SIGCHLD, SIG_IGN)
(не работает); призвание wait(int)
после установки только для чтения (происходит сбой, с ошибкой, равной 10 — «Нет дочерних процессов»); призвание kill(0, SIGCHLD)
(не работает).
Правильно ли я считаю, что это ошибка в mount
реализация у нас есть? Учитывая, что это ошибка, как я могу удалить несуществующие процессы и предотвратить заполнение таблицы идентификаторов процессов?
Некоторая дополнительная информация: кажется, что эта проблема не возникает, когда я запускаю тестовое приложение с strace
, Теперь я действительно озадачен!
В качестве обходного пути я обнаружил, что вызов mount()
команда изнутри pthread
позволяет больше не существовать jffs2_gcd_mtd0
процессы, которые нужно пожинать.
Я считаю, что это работает через следующий механизм: когда поток присоединяется, порождается jffs2_gcd_mtd0
процесс остался без родителя. Поэтому он наследуется init
, который затем пожинается, когда он закончен.
Если кто-то хотел бы исправить / расширить мое объяснение выше, пожалуйста!
Других решений пока нет …