(Реализация запуска ребёнка супервизора: supervisor:handle_start_child/2)
Поскольку супервизор — это такой же процесс, при этом от него требуется атомарность, а запросы на запуск — сообщения с ответами на них,
на время инита супервизор лочится, и процесс А получит пид чуть-чуть раньше, чем Б, потому что запрос от Б обработается супервизором сразу после завершения обработки запроса от А.
А вот порядок, в котором А и Б будут обрабатывать эти ответы (читай: будут поставлены на исполнение), никто не может гарантировать, особенно в случае многопроцессорной системы (там они могут делать это одновременно),
особенно если в той же системе ещё что-то происходит, и на шедулерах ненулевые очереди.
В качестве возможного сценария:
* на время инита супервизор засыпает, поэтому новый процесс может выполняться на том же шедулере — так меньше данных гоняется туда-сюда
* после инита запущенный процесс засыпает, потому что ему больше нечего делать, и на том же шедулере может продолжить выполнение супервизор
* супервизор что-то ответил процессу А и продолжает исполняться, потому что в очереди ещё есть сообщение от Б.
* А помечается как runnable, но на том же шедулере, что и супервизор, выполняться прямо сейчас не может, поэтому начинает исполняться на другом шедулере
* супервизор ответил процессу Б и уснул, потому что больше сообщений нет
* Б может продолжить выполнение на том же шедулере, что и супервизор. На этом же шедулере свежезапущенный ребёнок.
* Б посылает сообщение новому процессу и засыпает. После этого новый процесс может сразу же начать работать на тот же шедулере (который для него родной)
В итоге получается, что А хоть и получает ответ с пидом раньше, чем Б, но может выполняться на другом шедулере, тратя время на синхронизацию и копирование сообщений между шедулерами.
Тем временем связка супервизор–Б–ребёнок может работать на одном шедулере, экономя время.