🎲 — mikrobloggeriet olorm — olorm-17 · olorm-18 · olorm-19
Jeg har lagt merke til likheten mellom Go channels og Unix (named) pipes.
Go’s approach to concurrency […] can also be seen as a type-safe generalization of Unix pipes.
Først, hva er named pipes igjen?
command | grep foo
er en “vanlig” pipe og kan ses på som en spesialisering av en named pipe:
mkfifo mypipe
command > mypipe &
<mypipe grep foo
rm mypipe
Selv om det opprettes et filnavn, vil ikke data skrives til fila. Named pipes gir mye mer fleksibilitet for sending og lesing av meldinger enn en navnløs pipeline.
A Tour of Go - Concurrency introduserer channels med kode som summerer tall med to goroutines. Sammenlign med min implementasjon i UNIX shell:
#!/bin/bash
set -e
sum() { c=$1; shift
sum=0
for v in $@; do
sum=$(( sum + v ))
done
echo $sum > $c # send sum to c
}
main() {
s=(7 2 8 -9 4 0)
c=/tmp/chan$$ guard=/tmp/pipeguard$$
mkfifo $c
mkfifo $guard; >$c <$guard &
n=$[ ${#s[@]} / 2 ]
sum $c ${s[@]:0:n} &
sum $c ${s[@]:n} &
{ read x; read y; } <$c # receive from c
echo $x $y $((x+y))
>$guard; wait
}
main
Jeg synes koden er veldig lik. mkfifo $FILNAVN
tilsvarer
navn := make(chan t)
.
$guard
opprettes som en (inaktiv) skriver til
$c
for at den ikke skal lukkes for tidlig. FIFOer (named
pipes) lukkes nĂĄr alle skrivere er lukket (ferdige).
sum $c ${s[@]:0:n} &
tilsvarer selvsagt
go sum(s[:len(s)/2], c)
. &
starter en
asynkron prosess, lignende som go
. Shell angir som kjent
argumenter som ord, uten paranteser og komma. Slice’en sendes som et
slags variadic argument, sĂĄ det er mest praktisk ĂĄ ha c
som
første parameter. (Håndteringen av array i main() er forøvrig eneste
Bash-isme i koden.)
Den siste linja i main()
er bare høfflig opprydding som
lukker FIFOene og avventer at alle prosessene er avsluttet.
Send gjerne spørsmål eller kommentarer til Richard Tingstad :)