Вчера я пытался скомпилировать пакет ROOT из исходного кода. Поскольку я собирал его на 6-ядерном компьютере-монстре, я решил пойти дальше и собрать с использованием нескольких ядер make -j 6
. Поначалу компиляция прошла гладко и очень быстро, но в какой-то момент make
зависала, используя 100% CPU только на одном ядре.
Я немного погуглил и нашел этот пост на досках объявлений ROOT. Поскольку я сам собрал этот компьютер, я беспокоился, что неправильно применил радиатор, а процессор перегрелся или что-то в этом роде. К сожалению, у меня нет холодильника на работе, чтобы я мог его вставить. ;-)
Я установил lm-sensors
пакет и make -j 6
снова запустил , на этот раз следя за температурой процессора. Несмотря на то, что он достиг высокой температуры (около 60 ° С), он никогда не превышал высокую или критическую температуру.
Я попытался запустить, make -j 4
но снова make
завис во время компиляции, на этот раз в другом месте.
В итоге я скомпилировал только что запущенный make
и все заработало нормально. Мой вопрос: почему он завис? Из-за того, что он остановился в двух разных точках, я бы предположил, что это было из-за какого-то состояния гонки, но я думаю, что он make
должен быть достаточно умным, чтобы все расставить в правильном порядке, поскольку он предлагает такую -j
возможность.
strace -p <pid>
и посмотреть, сможете ли вы узнать, на что он смотрит. strace покажет вам только системные вызовы (не вызовы функций), но он все равно может дать вам ценную информацию, если он вращается при просмотре или для определенного файла.-j >1
.$(shell ...)
конечном счете, выполнялась команда, которая ожидала ввода отstdin
. Это было вызвано тем, что переменная была пустой, и никакие аргументы файла не были переданы команде.Ответы:
У меня нет ответа на этот конкретный вопрос, но я могу попытаться дать вам подсказку о том, что может происходить: отсутствие зависимостей в Make-файлах.
Пример:
Если вы позвоните,
make target
все будет правильно скомпилировано. Компиляцияa.source
выполняется (произвольно, но детерминировано) в первую очередь. Затемb.source
выполняется компиляция .Но если у вас
make -j2 target
обеcompile
команды будут выполняться параллельно. И вы действительно заметите, что зависимости вашего Makefile нарушены. Вторая компиляция предполагает, чтоa.bytecode
она уже скомпилирована, но она не отображается в зависимостях. Так что ошибка может произойти. Правильная строка зависимости дляb.bytecode
должна быть:Возвращаясь к вашей проблеме, если вам не повезло, возможно, команда зависла в 100% цикле ЦП из-за отсутствия зависимости. Это, вероятно, то, что происходит здесь, отсутствующая зависимость не может быть обнаружена последовательной сборкой, но она была обнаружена вашей параллельной сборкой.
источник
Я не знаю, как долго у вас была машина, но моей первой рекомендацией было бы попробовать тест памяти и убедиться, что память работает нормально. Я знаю, что проблема часто не в памяти, но если это так, то лучше сначала устранить ее как причину, прежде чем пытаться отследить другие, вероятно, проблемы.
источник
Я понимаю, что это действительно старый вопрос, но он все еще появляется в верхней части результатов поиска, поэтому вот мое решение:
В GNU make есть механизм сервера заданий, который гарантирует, что make и его рекурсивные дочерние элементы не потребляют больше указанного числа ядер: http://make.mad-scientist.net/papers/jobserver-implementation/
Он опирается на канал, общий для всех процессов. Каждый процесс, который хочет обработать дополнительные дочерние элементы, должен сначала потреблять токены из канала, а затем отказаться от них после завершения. Если дочерний процесс не возвращает использованные им токены, верхний уровень make while навсегда зависает, ожидая их возврата.
https://bugzilla.redhat.com/show_bug.cgi?id=654822
Я столкнулся с этой ошибкой при сборке binutils с GNU make на моем компьютере Solaris, где «sed» не является GNU sed. Решив проблему с PATH, чтобы сделать sed == gsed приоритетным по отношению к системе sed, эта проблема была устранена. Я не знаю, почему Сед потребляет токены из трубы.
источник
ваша система может быть в порядке, но это может быть состояние гонки
make
при параллельном запуске сборок.Если что-то не так с вашей системой, это может привести к зависанию / падению для других сценариев, а не только при выполнении параллельных сборок.
источник
Это может быть условием гонки, но также, если вся необходимая компиляция выполняется параллельно и в ожидании других, связывание требует вашего времени на вашей машине. Я думаю, что если связывание ожидает параллельную предыдущую необходимую компиляцию, то вы получаете высокую частоту процессора при связывании потока независимо от того, что вы компилируете.
источник