Ontem eu estava tentando compilar o pacote ROOT a partir do código-fonte. Desde que eu estava compilando em uma máquina monstro de 6 núcleos, decidi ir em frente e construir usando vários núcleos usando make -j 6
. A compilação foi suave e muito rápida no início, mas em algum momento make
travou usando 100% da CPU em apenas um núcleo.
Eu pesquisei no Google e encontrei este post nos quadros de mensagens do ROOT. Desde que eu mesmo construí este computador, fiquei preocupado por não ter aplicado corretamente o dissipador de calor e a CPU estar superaquecendo ou algo assim. Infelizmente, não tenho uma geladeira aqui no trabalho onde posso colocá-la. ;-)
Instalei o lm-sensors
pacote e executei make -j 6
novamente, desta vez monitorando a temperatura da CPU. Embora tenha ficado alto (perto de 60 ° C), nunca passou da temperatura alta ou crítica.
Tentei correr, make -j 4
mas novamente fiquei make
suspenso em algum momento durante a compilação, desta vez em um local diferente.
No final, eu compilei apenas rodando make
e funcionou bem. Minha pergunta é: Por que estava pendurado? Devido ao fato de ter parado em dois pontos diferentes, acho que foi devido a algum tipo de condição de corrida, mas acho que make
deveria ser inteligente o suficiente para colocar tudo na ordem certa, pois oferece a -j
opção.
strace -p <pid>
e veja se você consegue descobrir o que ele está procurando /. O strace mostrará apenas syscalls (não chamadas de função), mas ainda poderá fornecer informações valiosas se estiver girando enquanto você olha ou procura um arquivo específico.-j >1
.$(shell ...)
estava executando um comando que estava aguardando a entrada destdin
. Isso foi causado quando uma variável estava vazia e nenhum argumento do arquivo foi passado para o comando.Respostas:
Não tenho uma resposta para essa questão precisa, mas posso tentar dar uma dica do que pode estar acontecendo: Faltando dependências no Makefiles.
Exemplo:
Se você ligar,
make target
tudo será compilado corretamente. A compilação dea.source
é realizada (arbitrariamente, mas deterministicamente) primeiro. Em seguida, a compilaçãob.source
é realizada.Mas se os
make -j2 target
doiscompile
comandos serão executados em paralelo. E você perceberá que as dependências do Makefile estão quebradas. A segunda compilação assume quea.bytecode
já está compilada, mas não aparece nas dependências. Portanto, é provável que ocorra um erro. A linha de dependência correta parab.bytecode
deve ser:Para voltar ao seu problema, se você não tiver sorte, é possível que um comando seja interrompido em um loop de 100% da CPU, devido a uma dependência ausente. Provavelmente é o que está acontecendo aqui, a dependência que faltava não pôde ser revelada por uma compilação sequencial, mas foi revelada pela sua compilação paralela.
fonte
Não sei quanto tempo você está com a máquina, mas minha primeira recomendação seria tentar um teste de memória e verificar se a memória está funcionando corretamente. Sei que muitas vezes não é a memória que é o problema, mas, se for, é melhor eliminá-lo como uma causa antes de tentar localizar outros problemas prováveis.
fonte
Sei que essa é uma pergunta muito antiga, mas ela ainda aparece no topo dos resultados de pesquisa, então aqui está a minha solução:
O GNU make possui um mecanismo de servidor de tarefas para garantir que o make e seus filhos recursivos não consumam mais do que o número especificado de núcleos: http://make.mad-scientist.net/papers/jobserver-implementation/
Ele se baseia em um canal compartilhado por todos os processos. Cada processo que deseja bifurcar filhos adicionais precisa primeiro consumir tokens do cano e depois abandoná-los quando terminar. Se um processo filho não retornar os tokens que consumiu, o nível superior ficará bloqueado para sempre aguardando a devolução.
https://bugzilla.redhat.com/show_bug.cgi?id=654822
Encontrei este erro ao criar binutils com o GNU make na minha caixa Solaris, onde "sed" não é GNU sed. Brincar com o PATH para fazer com que o sed == gsed tenha prioridade sobre o sistema sed corrigiu o problema. Não sei por que o sed estava consumindo tokens do cano, no entanto.
fonte
seu sistema pode estar ok, mas pode ser uma condição de corrida acontecendo
make
ao executar compilações em paralelo.Se algo estiver errado com o seu sistema, ele travaria / trava em outros cenários, não apenas ao fazer compilações paralelas.
fonte
Isso pode ser uma condição de corrida, mas também se toda a compilação necessária for feita em paralelo e aguardando outras pessoas, a vinculação leva tempo na sua máquina. Eu acho que se o link aguarda a compilação necessária anterior em paralelo, você obtém alta frequência de CPU no encadeamento de link, independentemente do que compilar.
fonte