FAQ
Hello,

According to Effective Go:
A buffered channel can be used like a semaphore, for instance to limit
throughput.
In this example, incoming requests are passed to handle, which sends a
value into the
channel, processes the request, and then receives a value from the channel
to ready
the “semaphore” for the next consumer. The capacity of the channel buffer
limits
the number of simultaneous calls to process.
So it makes sense to me to buffer a channel for sending when we need more
throughput and responsiveness.

Then is there any case that receiving from a buffered channel can be useful?


Here's the full code to show what happens with buffered channel receiving.

http://play.golang.org/p/aouQ_RpKyr

package main

import "log"

func main() {
slice := []float64{23.0, 23, 23, -123.2323, 23, 123.23, -2.93, 23.1,
-101.34, 17.34}
sum := 0.0
for _, elem := range slice {
sum += elem
}

counter1 := NewChannelCounter(0)
defer counter1.Close()

for _, elem := range slice {
counter1.Add(elem)
}
val1 := counter1.Get()
if val1 != sum {
log.Fatalf("NewChannelCounter No Buffer wrong. Expected %v but got %v\n",
sum, val1)
}

counter2 := NewChannelCounter(10)
defer counter2.Close()

for _, elem := range slice {
counter2.Add(elem)
}
val2 := counter2.Get()
if val2 != sum {
log.Fatalf("NewChannelCounter No Buffer wrong. Expected %v but got %v\n",
sum, val2)
}
// 2015/08/07 17:49:25 NewChannelCounter No Buffer wrong. Expected
28.167699999999993 but got 23
}

// Counter is an interface for counting.
// It contains counting data as long as a type
// implements all the methods in the interface.
type Counter interface {
// Get returns the current count.
Get() float64

// Add adds the delta value to the counter.
Add(delta float64)
}

// ChannelCounter counts through channels.
type ChannelCounter struct {
valueChan chan float64
deltaChan chan float64
done chan struct{}
}

func NewChannelCounter(buf int) *ChannelCounter {
c := &ChannelCounter{
make(chan float64, buf),
make(chan float64, buf),
make(chan struct{}),
}
go c.Run()
return c
}

func (c *ChannelCounter) Run() {

var value float64

for {

// "select" statement chooses which of a set of
// possible send or receive operations will proceed.
select {

case delta := <-c.deltaChan:
value += delta

case <-c.done:
return

case c.valueChan <- value:
// Do nothing.

// If there is no default case, the "select" statement
// blocks until at least one of the communications can proceed.
default:
// default clauses in the select statements
// execute when no other case is ready
continue
}

}
}

func (c *ChannelCounter) Get() float64 {
return <-c.valueChan
}

func (c *ChannelCounter) Add(delta float64) {
c.deltaChan <- delta
}

func (c *ChannelCounter) Close() {
c.done <- struct{}{}
close(c.deltaChan)
}



When I buffered the receiver, it gets non-deterministic, because receiving
from the buffered channel
is non-blocking, and I can't think of any way to make this work correctly.
Or am I doing something wrong?


Thanks!

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Search Discussions

Discussion Posts

Follow ups

Related Discussions

Discussion Navigation
viewthread | post
posts ‹ prev | 1 of 6 | next ›
Discussion Overview
groupgolang-nuts @
categoriesgo
postedAug 8, '15 at 1:03a
activeAug 8, '15 at 3:18a
posts6
users3
websitegolang.org

People

Translate

site design / logo © 2021 Grokbase