Last active
April 8, 2016 16:35
-
-
Save vorandrew/90fe030829a8f8c3b7fb429b429da4f8 to your computer and use it in GitHub Desktop.
Channels
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
func main() { | |
var c chan string | |
c <- "let's get started" // deadlock | |
<-c // deadlock | |
c := make(chan string) | |
close(c) | |
c <- "let's get started" // panic | |
val, open := <-c // val = zero, open = false | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"net/http" | |
) | |
type job struct { | |
url string | |
resp chan *http.Response | |
} | |
type worker struct { | |
jobs chan *job | |
count int | |
} | |
func (w *worker) getter(done chan *worker) { | |
for { | |
j := <-w.jobs | |
resp, _ := http.Get(j.url) | |
j.resp <- resp | |
done <- w | |
} | |
} | |
func get(jobs chan *job, url string, answer chan string) { | |
resp := make(chan *http.Response) | |
jobs <- &job{url, resp} | |
r := <-resp | |
answer <- r.Request.URL.String() | |
} | |
func balancer(count int, depth int) chan *job { | |
jobs := make(chan *job) | |
done := make(chan *worker) | |
workers := make([]*worker, count) | |
for i := 0; i < count; i++ { | |
workers[i] = &worker{make(chan *job, depth), 0} | |
go workers[i].getter(done) | |
} | |
go func() { | |
for { | |
var free *worker | |
min := depth | |
for _, w := range workers { | |
if w.count < min { | |
free = w | |
min = w.count | |
} | |
} | |
var jobsource chan *job | |
if free != nil { | |
jobsource = jobs | |
} | |
select { | |
case j := <-jobsource: | |
free.jobs <- j | |
free.count++ | |
case w := <-done: | |
w.count-- | |
} | |
} | |
}() | |
return jobs | |
} | |
func main() { | |
jobs := balancer(10, 10) | |
answer := make(chan string) | |
for { | |
var url string | |
if _, err := fmt.Scanln(&url); err != nil { | |
break | |
} | |
go get(jobs, url, answer) | |
} | |
for u := range answer { | |
fmt.Printf("%s\n", u) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import "net/http" | |
type work struct { | |
url string | |
resp chan *http.Response | |
} | |
func getter(w chan work) { | |
for { | |
do := <-w | |
resp, _ := http.Get(do.url) | |
do.resp <- resp | |
} | |
} | |
func main() { | |
w := make(chan work) | |
go getter(w) | |
resp := make(chan *http.Response) | |
w <- work{"http://cdnjs.cloudflare.com/jquery/1.9.1/jquery.min.js", resp} | |
r := <-resp | |
// ... do something | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
func worker(start chan bool) { | |
<-start | |
// ... do stuff | |
} | |
func main() { | |
start := make(chan bool) | |
for i := 0; i < 100; i++ { | |
go worker(start) | |
} | |
close(start) | |
// ... all workers running now | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
func worker(start chan bool) { | |
<-start | |
// ... do stuff | |
} | |
func main() { | |
start := make(chan bool) | |
for i := 0; i < 100; i++ { | |
go worker(start) | |
} | |
close(start) | |
// ... all workers running now | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import "fmt" | |
func main() { | |
c1 := make(chan bool) | |
c2 := make(chan bool) | |
go func() { | |
for { | |
select { | |
case x, ok := <-c1: | |
if !ok { | |
c1 = nil | |
} | |
fmt.Println(x) | |
case x, ok := <-c2: | |
if !ok { | |
c2 = nil | |
} | |
fmt.Println(x) | |
} | |
if c1 == nil && c2 == nil { | |
return | |
} | |
} | |
}() | |
c1 <- true | |
// Disable the c1 case in the above select. | |
close(c1) | |
c2 <- true | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"math/rand" | |
) | |
func main() { | |
c := make(chan int) | |
d := make(chan bool) | |
go func(src chan int) { | |
for { | |
select { | |
case src <- rand.Intn(100): | |
case <-d: | |
src = nil | |
} | |
} | |
}(c) | |
// Print some random numbers. | |
fmt.Printf("%d\n", <-c) | |
fmt.Printf("%d\n", <-c) | |
// Disable random number generation. | |
d <- true | |
// Halts because c is now nil. | |
fmt.Printf("%d\n", <-c) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import "net/http" | |
type response struct { | |
resp *http.Response | |
url string | |
} | |
func get(url string, r chan response) { | |
if resp, err := http.Get(url); err == nil { | |
r <- response{resp, url} | |
} | |
} | |
func main() { | |
first := make(chan response) | |
for _, url := range []string{"http://code.jquery.com/jquery-1.9.1.min.js", | |
"http://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js", | |
"http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js", | |
"http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.9.1.min.js"} { | |
go get(url, first) | |
} | |
r := <-first | |
// ... do something | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import "time" | |
func worker() { | |
heartbeat := time.Tick(30 * time.Second) | |
for { | |
select { | |
// ... do some stuff | |
case <-heartbeat: | |
// ... do heartbeat stuff | |
} | |
} | |
} | |
func main() { | |
go worker() | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import "net" | |
func worker(messages chan string) { | |
for { | |
var msg string // ... generate a message | |
messages <- msg | |
} | |
} | |
func main() { | |
messages := make(chan string) | |
conn, _ := net.Dial("tcp", "example.com") | |
for i := 0; i < 100; i++ { | |
go worker(messages) | |
} | |
for { | |
msg := <-messages | |
conn.Write([]byte(msg)) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import "container/list" | |
func main() { | |
give := make(chan []byte) | |
get := make(chan []byte) | |
go func() { | |
q := new(list.List) | |
for { | |
if q.Len() == 0 { | |
q.PushFront(make([]byte, 100)) | |
} | |
e := q.Front() | |
select { | |
case s := <-give: | |
q.PushFront(s) | |
case get <- e.Value.([]byte): | |
q.Remove(e) | |
} | |
} | |
}() | |
// Gets a new buffer from the recycler. | |
buffer := <-get | |
// Give it back to the recycler. | |
give <- buffer | |
// Get the recycled buffer again. | |
buffer = <-get | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
func get(store chan []byte) []byte { | |
select { | |
case b := <-store: | |
return b | |
default: | |
return make([]byte, 100) | |
} | |
} | |
func give(store chan []byte, b []byte) { | |
select { | |
case store <- b: | |
default: | |
return | |
} | |
} | |
func main() { | |
// Create a store for the buffers. | |
store := make(chan []byte, 5) | |
// Gets a new buffer from the store. | |
buffer := get(store) | |
// Give it back to the store. | |
give(store, buffer) | |
// Get the recycled buffer again from the store. | |
buffer = get(store) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
https://www.youtube.com/watch?v=SmoM1InWXr0 | |
http://www.slideshare.net/cloudflare/a-channel-compendium |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import "fmt" | |
func main() { | |
id := make(chan string) | |
go func() { | |
var counter int64 = 1 | |
for { | |
id <- fmt.Sprintf("%x", counter) | |
counter += 1 | |
} | |
}() | |
fmt.Printf("%s\n", <-id) // will be 1 | |
fmt.Printf("%s\n", <-id) // will be 2 | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import "time" | |
func worker() { | |
for { | |
timeout := time.After(5 * time.Second) | |
select { | |
// ... do some stuff | |
case <-timeout: | |
// Close this go routine after the specified timeout. | |
return | |
} | |
} | |
} | |
func main() { | |
go worker() | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"time" | |
) | |
func main() { | |
c := make(chan bool) | |
go func() { | |
// ... do some stuff | |
time.Sleep(time.Second * 5) | |
close(c) | |
}() | |
// Halt for communication of data via the channel or for it to be closed. | |
<-c | |
fmt.Println("Done") | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
func worker(die chan bool) { | |
for { | |
select { | |
// ... do stuff cases | |
case <-die: | |
// ... do termination tasks | |
die <- true | |
return | |
} | |
} | |
} | |
func main() { | |
die := make(chan bool) | |
go worker(die) | |
die <- true | |
// Wait until the goroutine has terminated. | |
<-die | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment