Wczoraj próbowałem skompilować pakiet ROOT ze źródła. Ponieważ kompilowałem go na 6-rdzeniowej maszynie z potworami, postanowiłem zacząć budować za pomocą wielu rdzeni make -j 6
. Kompilacja przebiegła początkowo płynnie i naprawdę szybko, ale w pewnym momencie make
zawiesiła się przy użyciu 100% procesora tylko na jednym rdzeniu.
Zrobiłem trochę googlingu i znalazłem ten post na forach dyskusyjnych ROOT. Ponieważ sam zbudowałem ten komputer, martwiłem się, że nie zastosowałem prawidłowo radiatora, a procesor się przegrzał. Niestety nie mam tu w pracy lodówki, w której mogłabym ją włożyć. ;-)
Zainstalowałem lm-sensors
pakiet i uruchomiłem make -j 6
ponownie, tym razem monitorując temperaturę procesora. Chociaż stał się wysoki (blisko 60 ° C), nigdy nie przekroczył wysokiej lub krytycznej temperatury.
Próbowałem biegać, make -j 4
ale ponownie make
zawiesiłem się podczas kompilacji, tym razem w innym miejscu.
W końcu skompilowałem tylko działający make
i działało dobrze. Moje pytanie brzmi: dlaczego zwisało? Z uwagi na fakt, że zatrzymał się w dwóch różnych miejscach, sądzę, że było to spowodowane jakimś stanem wyścigowym, ale uważam, że make
powinno być wystarczająco sprytne, aby wszystko ułożyć we właściwej kolejności, ponieważ oferuje taką -j
opcję.
strace -p <pid>
I sprawdzić, czy możesz dowiedzieć się, na co on patrzy / na co. strace pokaże tylko wywołania systemowe (nie wywołania funkcji), ale nadal może dostarczyć cennych informacji, jeśli obraca się podczas przeglądania lub określonego pliku.-j >1
.$(shell ...)
ostatecznie uruchomiono polecenie, które czekało na dane wejściowestdin
. Stało się tak, gdy zmienna była pusta i do komendy nie przekazano argumentów pliku.Odpowiedzi:
Nie mam odpowiedzi na ten konkretny problem, ale mogę spróbować dać ci wskazówkę, co może się dziać: brak zależności w plikach Makefiles.
Przykład:
Jeśli zadzwonisz,
make target
wszystko skompiluje się poprawnie. Kompilacjaa.source
jest wykonywana (arbitralnie, ale deterministycznie) w pierwszej kolejności. Następnieb.source
wykonywana jest kompilacja .Ale jeśli
make -j2 target
obiecompile
komendy będą uruchamiane równolegle. I faktycznie zauważysz, że zależności twojego Makefile są zepsute. Zakładaa.bytecode
się, że druga kompilacja jest już skompilowana, ale nie pojawia się w zależnościach. Prawdopodobnie wystąpi błąd. Prawidłową linią zależności dlab.bytecode
powinno być:Aby powrócić do problemu, jeśli nie masz szczęścia, możliwe jest zawieszenie się polecenia w 100% pętli procesora z powodu braku zależności. Prawdopodobnie tak się dzieje tutaj, brakująca zależność nie mogła zostać ujawniona przez kompilację sekwencyjną, ale została ujawniona przez kompilację równoległą.
źródło
Nie wiem, jak długo masz maszynę, ale moim pierwszym zaleceniem byłoby przetestowanie pamięci i sprawdzenie, czy pamięć działa poprawnie. Wiem, że często problemem nie jest pamięć, ale jeśli tak, to najlepiej jest ją najpierw wyeliminować, zanim spróbujesz wyśledzić inne prawdopodobne problemy.
źródło
Zdaję sobie sprawę, że to naprawdę stare pytanie, ale wciąż pojawia się na górze wyników wyszukiwania, więc oto moje rozwiązanie:
GNU make posiada mechanizm serwera zadań, aby zapewnić make i jego rekurencyjne dzieci nie zużywają więcej niż określona liczba rdzeni: http://make.mad-scientist.net/papers/jobserver-implementation/
Opiera się na potoku wspólnym dla wszystkich procesów. Każdy proces, który chce rozwidlić dodatkowe elementy potomne, musi najpierw zużyć tokeny z potoku, a następnie zrezygnować z nich po zakończeniu. Jeśli proces potomny nie zwróci zużytych tokenów, najwyższy poziom sprawia, że podczas zawieszenia na zawsze czeka na ich zwrot.
https://bugzilla.redhat.com/show_bug.cgi?id=654822
Napotkałem ten błąd podczas budowania binutils z GNU make na moim komputerze Solaris, gdzie „sed” nie jest GNU sed. Poprawienie PATH, aby sed == gsed miało pierwszeństwo przed sedem systemowym, rozwiązało problem. Nie wiem jednak, dlaczego sed zużywał żetony z fajki.
źródło
Twój system może być w porządku, ale może to być sytuacja wyścigu
make
podczas równoległego uruchamiania kompilacji.Jeśli coś jest nie tak z twoim systemem, zawiesiłoby się / zawiesiło w innych scenariuszach, nie tylko podczas wykonywania równoległych kompilacji.
źródło
Może to być warunek wyścigu, ale także jeśli wszystkie niezbędne kompilacje są wykonywane równolegle i czekają na innych, łączenie zajmuje dużo czasu na twoim komputerze. Myślę, że jeśli linkowanie czeka na poprzednią konieczną kompilację równolegle, to uzyskujesz wysoką częstotliwość procesora przy łączeniu wątku, co skompilujesz.
źródło