Bash bekommt Thread-Pools: Parallele Shell-Befehle mit begrenzter Nebenläufigkeit

Concurrent Shell Command Queues

Bash bekommt Thread-Pools: Parallele Shell-Befehle mit begrenzter Nebenläufigkeit

Der Autor zeigt, wie man in Bash eine Warteschlange für Shell-Befehle baut, die parallel ausgeführt werden, aber die Nebenläufigkeit begrenzen. Die Lösung nutzt mkfifo und xargs -P, um einen Thread-Pool nachzubilden. Befehle können nach und nach eingereicht werden, und Subshells erben die Warteschlange. Der Code ist für Bash und Zsh geeignet und enthält defensive Programmierung, hat aber bekannte Einschränkungen wie nicht gestreamte Ausgabe und nur eine Warteschlange pro Shell. Der Autor gibt zu, dass andere Sprachen wie Python besser geeignet wären, aber er hatte Freude an der Herausforderung.

Die Antwort lautet: Ja, aber es erfordert etwas Arbeit, um halbwegs robust und portabel zu sein.
  1. js2

    > Wie man Shell-Befehle parallel ausführt und dabei ihre Nebenläufigkeit begrenzt.

    Je nach Aufgabe ein Makefile generieren und es ausführen mit:

    make -j <concurrency>

    > Mein ursprünglicher Anwendungsfall hatte damit zu tun, eine große Anzahl von Web-Anfragen zu stellen

    Das ist tatsächlich der Anwendungsfall, der mich vor wahrscheinlich 20 Jahren dazu gebracht hat, über die Verwendung eines Makefiles für Nebenläufigkeit nachzudenken. Eine Regel zum Herunterladen jeder URL in eine Datei. Dann ein einfaches `make -j <jobs>` mit welcher Nebenläufigkeit auch immer ich wollte, und als Bonus: bereits heruntergeladene Dateien werden automatisch übersprungen. z. B.:

    BASE := https://example.com/files

    FILES := a.txt b.txt c.txt d.txt e.txt

    .DELETE_ON_ERROR:

    all: $(FILES)

    $(FILES):

    curl -sS --fail --max-time 30 -o $@ $(BASE)/$@

    Oder, um eines der Beispiele aus dem Blogbeitrag nachzuahmen:

    SHELL := bash

    .SHELLFLAGS := -o pipefail -c

    N := 1 2 3 4 5

    REQS := $(N:%=req-%)

    .PHONY: all $(REQS)

    all: $(REQS)

    $(REQS): req-%:

    @curl -sS --fail-with-body --max-time 10 -X POST -H 'Content-Type: application/json' \

    -d '{"request": $*}' https://postman-echo.com/post | jq -c .json

    Ausführen mit:

    $ make -O -j 3

    > Man muss nicht alle Befehle im Voraus kennen, die ausgeführt werden sollen; man kann dem Programm im Laufe der Zeit Befehle übergeben.

    Ah, ja, das steckt Make tatsächlich in dieselbe Schublade wie `xargs -P` / GNU `parallel` und erfordert etwas Clevereres.

  2. reconquestio

    Es gibt auch GNU Parallels sem: https://www.gnu.org/software/parallel/sem.html

    sem --id jobs -j 2 'sleep 1; echo FIRST'

    sem --id jobs -j 2 'echo SECOND'

    sem --id jobs -j 2 'echo THIRD'

    sem --id jobs --wait

    SECOND

    THIRD

    FIRST

  3. 0cf8612b2e1e

    Ich mag pueue dafür wirklich sehr. Wie ein leichtgewichtiges Slurm oder parallel ohne den nervigen Zitierhinweis.

    https://github.com/Nukesor/pueue

Mehr von diesem Tag

2026-11-13