funcmain() { var a[100000] int for i := 0; i < 100000; i++ { gofunc(i int) { for { a[i]++ // runtime.Gosched() } }(i) } time.Sleep(time.Millisecond) fmt.Println(a) }
执行上面的代码后cpu会跑满,可以使用runtime.Gosched()可以手动交出控制权。
channel是goroutine和goroutine的交互,发了数据没人收的话是会死锁的!
1 2 3 4 5 6 7 8 9 10 11 12
funcmain() { c:=make(chanint)
// 将1,2送入channel c <- 1 c <- 2
// 从channel中读取 n:= <-c fmt.Println(n) } // 报错:fatal error: all goroutines are asleep - deadlock!
funccreateWorker(id int)chan <- int { c := make(chanint) gofunc() { for n:= range(c){ fmt.Printf("Worker %d received %c \n",id, n) } }() return c }
funcmain() { var channels [5]chan<- int for i := 0; i < 5; i++ { channels[i] = createWorker(i) } for i := 0; i < 5; i++ { // createWorker 方法创建的channel具有方向性,只能向channel中发数据,如果试图从channel中读取数据将会报错 // n := <- channels[i] channels[i] <- 'a' + i } for i := 0; i < 5; i++ { channels[i] <- 'A' + i } time.Sleep(time.Millisecond) }
// Worker 0 received a // Worker 0 received A // Worker 2 received c // Worker 3 received d // Worker 1 received b // Worker 4 received e // Worker 1 received B // Worker 3 received D
funcdoWork(id int,c chanint,done chanbool) { for n:= range(c){ fmt.Printf("Worker %d received %c \n",id, n) done <- true } }
funccreateWorker(id int) worker { w := worker{ in: make(chanint), done: make(chanbool), } go doWork(id,w.in,w.done) return w }
funcmain() { var workers [5]worker for i := 0; i < 5; i++ { workers[i] = createWorker(i) } // 1个1个等 for i,worker := range(workers) { worker.in <- 'a' + i <-worker.done } for i,worker := range(workers) { worker.in <- 'A' + i <-worker.done } }
上面的代码会输出以下结果:
1 2 3 4 5 6 7 8 9 10
Worker 0 received a Worker 1 received b Worker 2 received c Worker 3 received d Worker 4 received e Worker 0 received A Worker 1 received B Worker 2 received C Worker 3 received D Worker 4 received E
type worker struct{ in chanint wg *sync.WaitGroup }
funcdoWork(id int,c chanint,wg *sync.WaitGroup) { for n:= range(c){ fmt.Printf("Worker %d received %c \n",id, n) wg.Done() } }
funccreateWorker(id int,wg *sync.WaitGroup) worker { w := worker{ in: make(chanint), wg:wg, } go doWork(id,w.in,wg) return w }
funcmain() { var workers [5]worker var wg sync.WaitGroup for i := 0; i < 5; i++ { workers[i] = createWorker(i,&wg) } wg.Add(10) for i,worker := range(workers) { worker.in <- 'a' + i } for i,worker := range(workers) { worker.in <- 'A' + i } wg.Wait() }
funcgenerator()chanint { out:=make(chanint) gofunc() { i:=0 for { time.Sleep(time.Duration(rand.Intn(1500)) * time.Millisecond) out <- i i++ } }() return out }
funcmain() { var c1,c2 = generator(),generator() tm := time.After(5 * time.Second) tick := time.Tick(time.Second) for { select { case n := <- c1: fmt.Println("receive from c1:",n) case n := <- c2: fmt.Println("receive from c2:",n) case <- time.After(500 * time.Millisecond): // 等待数据太慢 fmt.Println("timeout") case <- tick: fmt.Println("this will print every seconds") case <- tm: // 计时器终止后退出程序 fmt.Println("bye") return } } }
receive from c2: 0 receive from c1: 0 receive from c1: 1 receive from c2: 1 this will print every seconds receive from c2: 2 timeout receive from c1: 2 receive from c2: 3 this will print every seconds timeout receive from c1: 3 this will print every seconds receive from c1: 4 receive from c1: 5 receive from c2: 4 receive from c2: 5 receive from c2: 6 receive from c1: 6 this will print every seconds timeout receive from c2: 7 this will print every seconds bye