概述


goroutine 可能切换的点
- 非强占式
- I/O ,select
- channel
- 等待锁
- 调用函数
- runtime.Gosched()
只是参考,不能保证切换
代码channel
package mainimport ("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<- intfor 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 mainimport ("fmt""math/rand""time")func generator() chan int {out := make(chan int)go func() {i := 0for {time.Sleep(time.Duration(rand.Intn(1500)) *time.Millisecond)out <- ii++}}()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 []inttm := time.After(10 * time.Second)tick := time.Tick(time.Second)for {var activeWorker chan<- intvar activeValue intif len(values) > 0 {activeWorker = workeractiveValue = 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 mainimport ("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 intdone 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.WaitGroupvar workers [10]workerfor 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()}

