Hier, j'essayais de compiler le package ROOT à partir des sources. Comme je le compilais sur une machine monstre à 6 cœurs, j'ai décidé d'aller de l'avant et de construire en utilisant plusieurs cœurs en utilisant make -j 6
. La compilation s'est déroulée en douceur et très rapidement au début, mais à un moment donné, elle a été make
suspendue en utilisant 100% de CPU sur un seul cœur.
J'ai fait quelques recherches sur Google et j'ai trouvé ce message sur les babillards électroniques de ROOT. Depuis que j'ai construit cet ordinateur moi-même, je craignais de ne pas avoir correctement appliqué le dissipateur thermique et le processeur surchauffait ou quelque chose. Malheureusement, je n'ai pas de réfrigérateur ici au travail où je peux le coller. ;-)
J'ai installé le lm-sensors
package et exécuté à make -j 6
nouveau, cette fois en surveillant la température du processeur. Bien qu'elle soit devenue élevée (près de 60 ° C), elle n'a jamais dépassé la température élevée ou critique.
J'ai essayé de courir, make -j 4
mais j'ai de nouveau make
suspendu pendant la compilation, cette fois à un endroit différent.
En fin de compte, j'ai compilé juste en cours d'exécution make
et cela a bien fonctionné. Ma question est: pourquoi était-elle suspendue? En raison du fait qu'il s'est arrêté à deux endroits différents, je suppose que cela était dû à une sorte de condition de course, mais je pense qu'il make
devrait être assez intelligent pour tout mettre dans le bon ordre car il offre l' -j
option.
strace -p <pid>
et voir si vous pouvez découvrir ce qu'il cherche / cherche. strace ne vous montrera que les appels système (pas les appels de fonction), mais il pourrait toujours vous donner des informations précieuses s'il tourne en regardant ou pour un fichier particulier.-j >1
.$(shell ...)
exécutait finalement une commande qui attendait l'entrée destdin
. Cela était dû au fait qu'une variable était vide et qu'aucun argument de fichier n'était transmis à la commande.Réponses:
Je n'ai pas de réponse à ce problème précis, mais je peux essayer de vous donner un indice de ce qui peut se produire: Dépendances manquantes dans les Makefiles.
Exemple:
Si vous appelez,
make target
tout se compilera correctement. La compilation dea.source
est effectuée (arbitrairement, mais de façon déterministe) en premier. Ensuite, la compilation deb.source
est effectuée.Mais si vous les
make -j2 target
deuxcompile
commandes seront exécutées en parallèle. Et vous remarquerez en fait que les dépendances de votre Makefile sont brisées. La deuxième compilation suppose qu'ellea.bytecode
est déjà compilée, mais elle n'apparaît pas dans les dépendances. Une erreur est donc susceptible de se produire. La ligne de dépendance correcte pourb.bytecode
doit être:Pour revenir à votre problème, si vous n'êtes pas chanceux, il est possible qu'une commande se bloque dans une boucle 100% CPU, en raison d'une dépendance manquante. C'est probablement ce qui se passe ici, la dépendance manquante n'a pas pu être révélée par une génération séquentielle, mais elle a été révélée par votre génération parallèle.
la source
Je ne sais pas depuis combien de temps vous avez la machine, mais ma première recommandation serait d'essayer un test de mémoire et de vérifier que la mémoire fonctionne correctement. Je sais que ce n'est souvent pas la mémoire qui est le problème, mais si c'est le cas, il est préférable de l'éliminer en tant que cause avant d'essayer de trouver d'autres problèmes probables.
la source
Je me rends compte que c'est une très vieille question, mais elle apparaît toujours en haut des résultats de recherche, alors voici ma solution:
GNU make dispose d'un mécanisme de serveur de travail pour garantir que make et ses enfants récursifs ne consomment pas plus que le nombre spécifié de cœurs: http://make.mad-scientist.net/papers/jobserver-implementation/
Il s'appuie sur un canal partagé par tous les processus. Chaque processus qui veut créer des enfants supplémentaires doit d'abord consommer des jetons du tuyau, puis les abandonner une fois terminé. Si un processus enfant ne retourne pas les jetons qu'il a consommés, la marque de niveau supérieur se bloque pour toujours en attendant leur retour.
https://bugzilla.redhat.com/show_bug.cgi?id=654822
J'ai rencontré cette erreur lors de la construction de binutils avec GNU make sur ma boîte Solaris, où "sed" n'est pas GNU sed. Jouer avec PATH pour que sed == gsed soit prioritaire sur le système sed a résolu le problème. Je ne sais pas pourquoi sed consommait des jetons de la pipe, cependant.
la source
votre système peut être correct, mais il peut s'agir d'une situation de concurrence critique
make
lors de l'exécution de builds en parallèle.Si quelque chose ne va pas avec votre système, il se bloquerait / planterait pour d'autres scénarios, pas seulement lors des builds parallèles.
la source
Cela pourrait être une condition de concurrence, mais aussi si toute la compilation nécessaire se fait en parallèle et en attendant d'autres, la liaison prend votre temps sur votre machine. Je pense que si la liaison attend la compilation nécessaire précédente en parallèle, alors vous obtenez une fréquence de processeur élevée sur le lien de liaison tout ce que vous compilez.
la source