go 協程1
阿新 • • 發佈:2019-02-05
go 協程
更多幹貨
程式碼地址:
概述
-
goroutine 可能切換的點
-
非強佔式
-
I/O ,select
-
channel
-
等待鎖
-
呼叫函式
-
runtime.Gosched()
-
只是參考,不能保證切換
-
程式碼channel
package main import ( "fmt" "time" ) func worker(id int, c chan int) { for n := range c { fmt.Printf("Worker %d received %c\n", id, n) } } func createWorker(id int) chan<- int { c := make(chan int) go worker(id, c) return c } func chanDemo() { var channels [10]chan<- int for i := 0; i < 10; i++ { channels[i] = createWorker(i) } for i := 0; i < 10; i++ { channels[i] <- 'a' + i } for i := 0; i < 10; i++ { channels[i] <- 'A' + i } time.Sleep(time.Millisecond) } func bufferedChannel() { c := make(chan int, 3) go worker(0, c) c <- 'a' c <- 'b' c <- 'c' c <- 'd' time.Sleep(time.Millisecond) } func channelClose() { c := make(chan int) go worker(0, c) c <- 'a' c <- 'b' c <- 'c' c <- 'd' close(c) time.Sleep(time.Millisecond) } func main() { fmt.Println("Channel as first-class citizen") chanDemo() fmt.Println("Buffered channel") bufferedChannel() fmt.Println("Channel close and range") channelClose() }
select 程式碼
package main import ( "fmt" "math/rand" "time" ) func generator() chan int { out := make(chan int) go func() { i := 0 for { time.Sleep( time.Duration(rand.Intn(1500)) * time.Millisecond) out <- i i++ } }() return out } func worker(id int, c chan int) { for n := range c { time.Sleep(time.Second) fmt.Printf("Worker %d received %d\n", id, n) } } func createWorker(id int) chan<- int { c := make(chan int) go worker(id, c) return c } func main() { var c1, c2 = generator(), generator() var worker = createWorker(0) var values []int tm := time.After(10 * time.Second) tick := time.Tick(time.Second) for { var activeWorker chan<- int var activeValue int if len(values) > 0 { activeWorker = worker activeValue = values[0] } select { case n := <-c1: values = append(values, n) case n := <-c2: values = append(values, n) case activeWorker <- activeValue: values = values[1:] case <-time.After(800 * time.Millisecond): fmt.Println("timeout") case <-tick: fmt.Println( "queue len =", len(values)) case <-tm: fmt.Println("bye") return } } }
done 程式碼
package main import ( "fmt" "sync" ) func doWork(id int, w worker) { for n := range w.in { fmt.Printf("Worker %d received %c\n", id, n) w.done() } } type worker struct { in chan int done func() } func createWorker( id int, wg *sync.WaitGroup) worker { w := worker{ in: make(chan int), done: func() { wg.Done() }, } go doWork(id, w) return w } func chanDemo() { var wg sync.WaitGroup var workers [10]worker for i := 0; i < 10; i++ { workers[i] = createWorker(i, &wg) } wg.Add(20) for i, worker := range workers { worker.in <- 'a' + i } for i, worker := range workers { worker.in <- 'A' + i } wg.Wait() } func main() { chanDemo() }