Bash Multicore?



  • Hi,

    ich will in einem Shell-Skript vier Sub-Prozesse aufrufen (xsltproc-Aufrufe). Nun sollen die auf die verfügbaren CPU-Kerne verteilt werden. Außerdem soll nach den Aufrufen so lange das Skript blockiert werden, bis alle xsltproc-Aufrufe durchgelaufen sind. Geht das irgendwie?

    Ciao, Consolero.


  • Mod

    Prozesse im Hintergrund starten. Sofern du nicht spezielle Gegenmaßnahmen ergreifst, wird der Scheduler die Prozesse selbstständig so gut wie möglich verteilen. In bash kannst du mit man: wait auf das Beenden der Unterprozesse warten.



  • Das war ja viel unkomplizierter als ich dachte! Super, merci!



  • SeppJ schrieb:

    In bash kannst du mit man: wait auf das Beenden der Unterprozesse warten.

    Das möchte ich nochmal unterstreichen. Wenn sich nämlich ein Bash-Skript beendet, während noch Hintergrund-Prozesse laufen, dann werden die Hintergrund-Prozesse nicht abgeschossen, wie man vielleicht erwarten würde. Schlimmer noch, die Hintergrundprozesse werden nicht von der Parent-Shell übernommen, sondern an init weitergegeben. Das heißt, sie werden niemals mehr automatisch beendet, von einem System-Neustart abgesehen, und sind von keiner Shell aus mehr als jobs sichtbar.

    Es kann sehr unangenehme Effekte haben, wenn Hintergrund-Prozesse weiterlaufen und man damit nicht rechnet.

    Was deswegen besser sein könnte (sofern es in deinen Anwendungsfall passt), wäre xargs mit der Option -P. Das startet mehrere Prozesse parallel und kümmert sich selber darum, dass immer die maximal mögliche Anzahl an Prozessen parallel läuft. Vor allem aber lässt xargs die Kindprozesse nicht leben, wenn es vorzeitig beendet wird.



  • Die Verteufelung von Prozessen. Es lebe der Deamon.



  • Hm, mit xargs kriege ich es nicht so richtig hin.

    Angenommen mein Aufruf sieht bis jetzt so aus:

    xsltproc --xinclude my_stylesheet1.xml my_input.xml >> my_file1.txt
    xsltproc --xinclude my_stylesheet2.xml my_input.xml >> my_file2.txt
    xsltproc --xinclude my_stylesheet3.xml my_input.xml >> my_file3.txt
    xsltproc --xinclude my_stylesheet4.xml my_input.xml >> my_file4.txt
    

    Dann müsste ja irgendwie sowas möglich sein:

    {"--xinclude my_stylesheet1.xml my_input.xml >> my_file1.txt" "--xinclude my_stylesheet2.xml my_input.xml >> my_file2.txt" "--xinclude my_stylesheet3.xml my_input.xml >> my_file3.txt" "--xinclude my_stylesheet4.xml my_input.xml >> my_file4.txt" | xargs -n 1 -p 4 xsltproc
    

    So klappt es natürlich nicht, weil ich xsltproc nicht einfach eine Liste zu-pipen kann. Aber wie macht man's richtig?



  • Consolero schrieb:

    So klappt es natürlich nicht, weil ich xsltproc nicht einfach eine Liste zu-pipen kann. Aber wie macht man's richtig?

    Das ist mit xargs nur äußerst umständlich machbar. Wie das mit xargs geht, ist dem Leser als Übung überlassen. 😉

    Mit einfachen Hintergrundprozessen ist es zwar auch nicht sonderlich schön, aber zumindest ein bisschen einfacher umzusetzen als mit xargs. Im Prinzip einfach mit & die ganzen Prozesse starten und dann mit wait auf deren Ende warten.

    Besonders robust ist es dann halt nicht, denn wenn der User das Skript mit ^C abbricht, laufen die Hintergrundprozesse alle weiter, völlig unsichtbar für den Nutzer.

    Siehe auch:
    I want to process a bunch of files in parallel, and when one finishes, I want to start the next. And I want to make sure there are exactly 5 jobs running at a time.
    Vor allem der letzte Satz dort ist nicht verkehrt: "If you need something more sophisticated than these, you're probably looking at the wrong language."



  • Naja, es gäbe da schon auch noch GNU Parallel, aber ich verwende typischerweise einfach gleich Ruby, wenn ich irgendwelche alten Shellskripte parallelisieren möchte.



  • Christoph schrieb:

    Besonders robust ist es dann halt nicht, denn wenn der User das Skript mit ^C abbricht, laufen die Hintergrundprozesse alle weiter, völlig unsichtbar für den Nutzer.

    Völlig unsichtbar? Nicht ganz! Eine Shell unbeugsamer ps -A s leistet noch immer Widerstand. 😉



  • Lycanthropist schrieb:

    Christoph schrieb:

    Besonders robust ist es dann halt nicht, denn wenn der User das Skript mit ^C abbricht, laufen die Hintergrundprozesse alle weiter, völlig unsichtbar für den Nutzer.

    Völlig unsichtbar? Nicht ganz! Eine Shell unbeugsamer ps -A s leistet noch immer Widerstand. 😉

    Wenn man nicht weiß, wie der Prozess heißt, kann es aber recht lange dauern, ihn dort zu finden. Aber ja, völlig unsichtbar war übertrieben.


Anmelden zum Antworten