Проблема Из Реальной Жизни: Как Восстановить Дерево Процессов В Linux

Мы разрабатываем проект CRIU (Проверка/Восстановление в пользовательском пространстве) и у нас возникла довольно интересная проблема о том, как восстановить исходное дерево процессов.

Предлагаю вам попробовать ее решить.

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

Одной из подзадач восстановления является поиск последовательности действий по восстановлению дерева процессов.

Входные данные содержат набор параметров для каждого процесса: уникальный идентификатор (PID), ссылку на родителя (PPID), идентификатор сеанса (SID).



Проблема из реальной жизни: как восстановить дерево процессов в Linux

Правила, по которым живут процессы в Linux

  • Иерархия процессов в Linux имеет древовидную структуру.

  • Каждый процесс имеет уникальный PID (идентификатор процесса).

  • Каждый процесс имеет SID (идентификатор сеанса).

    Он наследуется от родителя, и в любой момент времени процесс может принять решение стать лидером, после чего его SID будет равен PID.

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

  • Родитель может подобрать (уничтожить) любого из дочерних зомби.

  • Корневой процесс всегда является потомком-жнецом, остальные необязательны (эту функциональность они могут включать и выключать в любой момент).

  • Процессы могут рождаться не только вниз (стать ребенком), но и вбок (стать братом).

Команды:
  • fork(pid) – создает процесс с заданным PID, который станет дочерним по отношению к текущему.

  • clone(pid, CLONE_PARENT) – создается процесс с заданным PID, который станет братом текущего
  • prctl(PR_SET_CHILD_SUBREAPER, flag) – говорит, что текущий процесс будет дочерним жнецом, если flag = true, и что текущий процесс отказывается быть дочерним жнецом, если flag = false
  • setsid() — делает текущий процесс лидером сессии.

  • exit() — процесс умирает, но не исчезает, а переходит в состояние «зомби».

    Все его потомки переезжают к ближайшему жнецу детей.

  • wait(pid) — выбирает (уничтожает) зомби с заданным PID. Эту операцию может выполнить только родитель зомби.

Пример входных данных Входные данные содержат строку для каждого процесса.

Каждая строка содержит 3 числа pid, ppid (pid родительского процесса), sid и флаг зомби, который имеет значение 0, если процесс мертв («зомби»), и 1, если процесс жив.

1 0 1 1 6 1 6 1 8 6 7 1 15 6 12 1 10 1 10 1 11 10 7 1 13 10 12 1 Пример вывода 1: вилка(6) 6: вилка(7) 7: сетсид() 7: клон (8, CLONE_PARENT) 7: выход() 6: подождите() 8: вилка(9) 9: вилка(10) 10: вилка(11) 10: вилка(12) 12: сетсид() 12: клон (13, CLONE_PARENT) 12: клон (14, CLONE_PARENT) 12: выход() 10: подожди(12) 14: вилка(15) 6: prctl(PR_SET_CHILD_SUBREAPER, 1) 14: выход() 10: подожди(14) 6: прктл(PR_SET_CHILD_SUBREAPER, 0) 9: выход() 8: подожди(9) 6: сетсид() 10: сетсид() Теги: #criu #linux #системное программирование #алгоритмы #олимпиадное программирование #олимпиадные задачи #спортивное программирование #Системное программирование #Алгоритмы

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.