Skip to content

Instantly share code, notes, and snippets.

@tanaka51
Last active December 26, 2015 05:29
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tanaka51/7100950 to your computer and use it in GitHub Desktop.
Save tanaka51/7100950 to your computer and use it in GitHub Desktop.
share a variable between some goroutines
package main
import (
"fmt"
"math/rand"
"sync"
"time"
)
const (
WORKER_LIMIT = 10
)
var Target []int = []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30}
type visited struct {
mu sync.Mutex
mark map[int]bool
}
func (v *visited) Visit(visit int) {
v.mu.Lock()
v.mark[visit] = true
v.mu.Unlock()
}
func (v *visited) Seen(target int) (seen bool) {
v.mu.Lock()
seen = v.mark[target]
v.mu.Unlock()
return
}
func worker() <-chan int {
var wg sync.WaitGroup
receiver := make(chan int)
visited := visited{mark: make(map[int]bool)}
go func() {
defer close(receiver)
for i := 0; i < WORKER_LIMIT; i++ {
wg.Add(1)
go func(no int) {
defer wg.Done()
for _, target := range Target {
if visited.Seen(target) {
continue
}
visited.Visit(target)
fmt.Printf("no %2d: %2d\n", no, target)
time.Sleep(time.Duration(rand.Intn(1e3)) * time.Millisecond)
}
}(i)
}
wg.Wait()
}()
return receiver
}
func main() {
receiver := worker()
for {
_, ok := <-receiver
if !ok {
fmt.Println("finish")
return
}
}
}
$ go run main.go
no 0: 1
no 1: 2
no 2: 3
no 3: 4
no 4: 5
no 5: 6
no 6: 7
no 7: 8
no 8: 9
no 9: 10
no 7: 11
no 4: 12
no 8: 13
no 4: 14
no 3: 15
no 9: 16
no 4: 17
no 0: 18
no 2: 19
no 1: 20
no 4: 21
no 9: 22
no 8: 23
no 1: 24
no 2: 25
no 2: 26
no 7: 27
no 6: 28
no 0: 29
no 5: 30
finish
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment