Ayer estaba tratando de compilar el paquete ROOT desde la fuente. Como lo estaba compilando en una máquina monstruo de 6 núcleos, decidí seguir adelante y construir usando múltiples núcleos make -j 6
. La compilación se realizó sin problemas y realmente rápido al principio, pero en algún momento se make
bloqueó usando 100% de CPU en un solo núcleo.
Busqué en Google y encontré esta publicación en los foros de ROOT. Desde que construí esta computadora, me preocupaba no haber aplicado correctamente el disipador de calor y la CPU se estaba sobrecalentando o algo así. Desafortunadamente, no tengo un refrigerador aquí en el trabajo en el que pueda meterlo. ;-)
Instalé el lm-sensors
paquete y corrí make -j 6
nuevamente, esta vez monitoreando la temperatura de la CPU. Aunque se puso alto (cerca de 60 C), nunca pasó la temperatura alta o crítica.
Traté de correr, make -j 4
pero nuevamente make
colgué en algún momento durante la compilación, esta vez en un lugar diferente.
Al final, compilé simplemente corriendo make
y funcionó bien. Mi pregunta es: ¿por qué estaba colgando? Debido al hecho de que se detuvo en dos puntos diferentes, supongo que se debió a algún tipo de condición de carrera, pero creo que make
debería ser lo suficientemente inteligente como para tener todo en el orden correcto, ya que ofrece la -j
opción.
strace -p <pid>
y ver si puede averiguar qué está mirando / buscando. strace solo le mostrará llamadas al sistema (no llamadas a funciones), pero aún podría brindarle información valiosa si está girando mientras mira o busca un archivo en particular.-j >1
.$(shell ...)
finalmente estaba ejecutando un comando que estaba esperando la entrada destdin
. Esto se produjo cuando una variable estaba vacía y no se pasaron argumentos de archivo al comando.Respuestas:
No tengo una respuesta a este problema preciso, pero puedo intentar darle una pista de lo que puede estar sucediendo: faltan dependencias en Makefiles.
Ejemplo:
Si llamas
make target
todo se compilará correctamente. La compilación dea.source
se realiza (arbitrariamente, pero determinísticamente) primero. Luegob.source
se realiza la compilación de .Pero si tu
make -j2 target
amboscompile
comandos se ejecutarán en paralelo. Y realmente notará que las dependencias de su Makefile están rotas. La segunda compilación suponea.bytecode
que ya está compilada, pero no aparece en las dependencias. Por lo tanto, es probable que ocurra un error. La línea de dependencia correcta parab.bytecode
debería ser:Para volver a su problema, si no tiene suerte, es posible que un comando se bloquee en un ciclo de CPU 100%, debido a una dependencia que falta. Eso es probablemente lo que está sucediendo aquí, la dependencia faltante no pudo ser revelada por una compilación secuencial, pero ha sido revelada por su compilación paralela.
fuente
No sé cuánto tiempo ha tenido la máquina, pero mi primera recomendación sería probar una prueba de memoria y verificar que la memoria funciona correctamente. Sé que a menudo el problema no es la memoria, pero si lo es, lo mejor es eliminarlo como causa antes de intentar localizar otros problemas probablemente.
fuente
Me doy cuenta de que esta es una pregunta muy antigua, pero aún aparece en la parte superior de los resultados de búsqueda, así que aquí está mi solución:
GNU make tiene un mecanismo de servidor de trabajo para garantizar que make y sus hijos recursivos no consuman más que el número especificado de núcleos: http://make.mad-scientist.net/papers/jobserver-implementation/
Se basa en una tubería compartida por todos los procesos. Cada proceso que quiere bifurcar niños adicionales primero tiene que consumir fichas de la tubería, luego renunciar a ellas cuando haya terminado. Si un proceso secundario no devuelve los tokens que consumió, el nivel superior se realiza mientras se bloquea para siempre esperando que sean devueltos.
https://bugzilla.redhat.com/show_bug.cgi?id=654822
Encontré este error al construir binutils con GNU make en mi caja Solaris, donde "sed" no es GNU sed. Jugar con PATH para que sed == gsed tenga prioridad sobre el sistema sed solucionó el problema. Sin embargo, no sé por qué sed estaba consumiendo fichas de la tubería.
fuente
su sistema podría estar bien, pero podría ser una condición de carrera que ocurra con
make
cuando se ejecutan compilaciones en paralelo.Si algo está mal con su sistema, se bloqueará / bloqueará para otros escenarios, no solo al hacer compilaciones paralelas.
fuente
Esta podría ser una condición de carrera, pero también si toda la compilación necesaria se realiza en paralelo y esperando a otros, la vinculación lleva su tiempo en su máquina. Creo que si el enlace espera la compilación necesaria previa en paralelo, entonces obtienes una alta frecuencia de CPU en el hilo de enlace, lo que sea que compiles.
fuente