Hur man använder flertrådad bearbetning i Bash-skript

0
146
Aleksey Mnogosmyslov/Shutterstock.com < /figure>

Flertrådad programmering har alltid varit av intresse för utvecklare för att öka applikationsprestanda och optimera resursanvändning. Den här guiden kommer att presentera dig för grundläggande kodning av Bash med flera trådar.

Vad är multi-threaded programmering ?

En bild är värd tusen ord, och detta gäller när det gäller att visa skillnaden mellan enkel (1) trådprogrammering och flertrådad (& gt; 1) programmering i Bash:

sleep 1 sleep 1 & amp ; sömn 1

Vår första multi-threaded programmeringsinställning eller mini one-liner script kunde inte ha varit enklare; på första raden sover vi i en sekund med kommandot sleep 1. När det gäller användaren körde en enda tråd en enda viloläge på en sekund.

På den andra raden har vi två en-sekunders sömnkommandon. Vi går med dem med hjälp av en & amp; separator, som inte bara fungerar som en separator mellan de två sömnkommandona, utan också som en indikator för Bash för att starta det första kommandot i en bakgrundstråd.

Normalt skulle man avsluta ett kommando med hjälp av en semikolon (;). Om du gör det skulle kommandot köras och först sedan fortsätta till nästa kommando som anges bakom semikolon. Till exempel exekvering av sömn 1; sömn 1 skulle ta drygt två sekunder – exakt en sekund för det första kommandot, en sekund för det andra och en liten mängd systemoverhead för vart och ett av de två kommandona.

Men istället för att avsluta ett kommando med ett semikolon kan man använda andra kommandoterminatorer som Bash känner igen som & amp ;, & amp; & amp; och ||. & Amp; & amp; syntax är ganska oberoende av flertrådad programmering, det gör helt enkelt detta; fortsätt med att utföra det andra kommandot endast om det första kommandot lyckades. Den || är motsatsen till & amp; & amp; och kommer bara att utföra det andra kommandot om det första kommandot misslyckades.

Återgår till flertrådad programmering med & amp; eftersom vår kommandoterminator kommer att initiera en bakgrundsprocess som utför kommandot som föregår den. Den fortsätter sedan omedelbart med att köra nästa kommando i det aktuella skalet medan bakgrundsprocessen (tråden) lämnas för att köras av sig själv.

Annonsering

I kommandot kan vi se att en bakgrundsprocess startas (enligt [1] 445317 där 445317 är process -ID eller PID för den nystartade bakgrundsprocessen och [1] indikerar att detta är vår första bakgrundsprocess ) och det avslutas därefter (som indikeras av [1]+ Klar sömn 1).

Om du vill se ett ytterligare exempel på bakgrundsprocesshantering kan du läsa våra grunder för Bash Automation och Scripting (del 3) artikel. Dessutom kan Bash Process Termination Hacks vara av intresse.

Låt oss nu bevisa att vi effektivt kör två sömnprocesser samtidigt:

time sleep 1; eko 'klar' tid $ (sömn 1 & sömn 1); echo 'done'

Här startar vi vår sömnprocess under tid och vi kan se hur vårt enda trådade kommando kördes i exakt 1.003 sekunder innan vår kommandoradsfråga returnerades.

I det andra exemplet tog det dock ungefär samma tid (1.005 sekunder) även om vi utförde två perioder (och processer) av sömn, men inte i följd. Återigen använde vi en bakgrundsprocess för det första sömnkommandot, vilket ledde till (halv) parallell körning, dvs. flertrådad.

Annonsering

Vi använde också en subshell wrapper ($ (…)) runt våra två sömnkommandon för att kombinera dem tillsammans under tiden. Som vi kan se visar vår färdiga utdata på 1,005 sekunder och därför måste de två sömn 1 -kommandona ha körts samtidigt. Intressant är den mycket lilla ökningen av den totala bearbetningstiden (0,002 sekunder) som enkelt kan förklaras av den tid som krävs för att starta ett delskal och den tid som krävs för att starta en bakgrundsprocess.

Flertrådad (och bakgrund) processhantering

I Bash innefattar flertrådad kodning normalt bakgrundstrådar från ett huvudskript med en rad eller ett fullständigt Bash-skript. I huvudsak kan man tänka på flertrådad kodning i Bash som att starta flera bakgrundstrådar. När man börjar koda med flera trådar blir det snabbt klart att sådana trådar vanligtvis kommer att kräva lite hantering. Ta till exempel det fiktiva exemplet där vi startar fem samtidiga perioder (och processer) av sömn i ett Bash -skript;

#!/bin/bash sleep 10 & amp; sova 600 & amp; sova 1200 & amp; sova 1800 & amp; sova 3600 & amp;

När vi startar skriptet (efter att ha gjort det körbart med chmod +x rest .sh), ser vi ingen utmatning! Även om vi utför jobb (kommandot som visar eventuella bakgrundsjobb som pågår) finns det ingen utmatning. Varför?

Anledningen är att skalet som användes för att starta detta skript (dvs. det nuvarande skalet) inte är samma skal (inte heller samma tråd; att börja tänka i form av delskal som trådar i och för sig själva) som utförde den faktiska sömnen kommandon eller placerade dem i bakgrunden. Det var snarare (sub) skalet som startades när ./rest.sh kördes.

Låt oss ändra vårt skript genom att lägga till jobb i skriptet. Detta kommer att säkerställa att jobb utförs inifrån (under) skalet där det är relevant, samma som när perioderna (och processerna) av sömn startades.

Den här gången kan vi se listan över bakgrundsprocesser som startas tack vare jobbkommandot på slutet av manuset. Vi kan också se deras PID (Process Identifiers). Dessa PID: er är mycket viktiga när det gäller att hantera och hantera bakgrundsprocesser.

Annonsering

Ett annat sätt att få bakgrunden Process Identifier är att söka efter det omedelbart efter att ett program/en process har placerats i bakgrunden:

#!/bin/bash sleep 10 & amp; eko $ {!} sova 600 & amp; eko $ {!} sömn 1200 & amp; eko $ {!} sömn 1800 & amp; eko $ {!} sova 3600 & amp; echo $ {!}

I likhet med vårt jobb -kommando (med nya PID ’ s nu när vi startade om vårt rest.sh -skript), tack vare Bash $ {!} Variabeln som ekas, kommer vi nu att se de fem PID ’ s visas nästan omedelbart efter att skriptet startar: de olika sömnprocesserna placerades i bakgrundstrådarna efter varandra.

vänta kommandot

När vi har börjat vår bakgrund processer har vi inget annat att göra än att vänta på att de ska vara klara. Men när varje bakgrundsprocess kör en komplex deluppgift och vi behöver huvudskriptet (som startade bakgrundsprocesserna) för att återuppta körningen när en eller flera av bakgrundsprocesserna avslutas behöver vi ytterligare kod för att hantera detta.

Låt oss utöka vårt skript nu med kommandot vänta för att hantera våra bakgrundstrådar:

#!/Bin/bash sleep 10 & amp; T1 = $ {!} Sova 600 & amp; T2 = $ {!} Sova 1200 & amp; T3 = $ {!} Sova 1800 & amp; T4 = $ {!} Sova 3600 & amp; T5 = $ {!} Echo “Detta skript startade fem bakgrundstrådar som för närvarande körs med PID $ {T1}, $ {T2}, $ {T3}, $ {T4}, $ {T5}.” vänta $ {T1} eko “Tråd 1 (sovplats 10) med PID $ {T1} har slutförts!” vänta $ {T2} eko “Tråd 2 (sovplats 600) med PID $ {T2} har slutförts!”

Här utökade vi vårt skript med två väntekommandon som väntar på PID -anslutningen till den första och andra trådar för att avsluta. Efter 10 sekunder finns vår första tråd, och vi meddelas om detsamma. Steg för steg kommer detta skript att göra följande: starta fem trådar nästan samtidigt (även om själva starten av trådarna fortfarande är sekventiell och inte parallell) där var och en av de fem sömnen kommer att köras parallellt. < /p>

Huvudskriptet rapporterar sedan (sekventiellt) om den skapade tråden och väntar därefter på att process -ID för den första tråden avslutas. När det händer kommer det att sekventiellt rapportera om den första trådens avslutning och börja vänta på att den andra tråden ska sluta, etc.

Annonsering

Använda Bash -idiomen & amp ;, $ {!} Och vänta-kommandot ger oss stor flexibilitet när det gäller att köra flera trådar parallellt (som bakgrundstrådar) i Bash.

Avsluta

I den här artikeln utforskade vi Bash multi-threaded scripting grunderna. Vi introducerade bakgrundsprocessoperatören (& amp;) med några enkla exempel som visar både enkla och flertrådade sömnkommandon. Därefter tittade vi på hur man hanterar bakgrundsprocesser via de vanliga Bash -idiomen $ {!} Och väntar. Vi undersökte också jobbkommandot för att se körande bakgrundstrådar/processer.

Om du tyckte om att läsa den här artikeln, ta en titt på vår artikel om Bash Process Termination Hacks.