Reputation: 4253
Imagine I have a goroutine that reads from one channel and writes to another.
ch1 := make(chan int)
ch2 := make(chan int)
go func() {
for num := range ch1 {
ch2 <- num+1
}
}()
If ch2
is blocked, the goroutine will still read a value from ch1
, effectively introducing a buffer of 1 in the channel. Since I'm using channels for control flow I don't want any buffering.
How can I make a pipeline that executes in a completely lock-step fashion? Or put differently, how can I transfer a value from one channel to the next in one atomic operation?
I basically want to wait for both ch1
and ch2
to be at a rendezvous point.
Upvotes: 2
Views: 936
Reputation: 417827
You can't do this with 2 channels. In order to perform a send on ch2
, the value to be sent must already be ready, evaluated. Spec: Send statements:
Both the channel and the value expression are evaluated before communication begins.
So even if you would do this, which seemingly does not buffer the value in any variable:
ch2 <- (<- ch1)
Still, the receive from ch1
would be evaluated first, and only then would the send be attempted.
Which means that value must have already been received from ch1
. But you can't tell if anyone is "listening" on ch2
(meaning if a send on ch2
could proceed) without attempting to send on ch2
(and even if you could, there is no guarantee that attempting a send after a check there would still be someone listening on it).
Upvotes: 1