当前位置: 代码迷 >> 综合 >> go基础笔记----Goroutine and Channel
  详细解决方案

go基础笔记----Goroutine and Channel

热度:22   发布时间:2023-12-13 16:53:55.0
  • goroutine
package mainimport ("fmt""time"
)/*goroutine 类协程{定义{任何函数只需加上go就能送给调度器运行不需要在定义时区分是否时异步函数调度器在合适的点进行切换使用 -race来检测数据访问冲突}goroutine可能的切换点{1.I/O,select2.channel3.等待锁4.函数调用(有时)5.runtime.Gosched()   //在某个点愿意交出控制权6.以上只是参考,不能保证切换,不能保证在其他地方不切换}内部结构{调度器线程{goroutine*n}}}coroutine(协程){轻量级"线程"{非抢占式多任务处理,由协程主动交出控制权编译器/解释器/虚拟机层面的多任务多个协程可能在一个或多个线程上运行}子程序是协程的一个特例{普通函数{线程{main->doWork}}协程{线程(可能是多个线程,底层实现不用管){main<->doWork 有一个通道,数据可以双向流通,控制权也可双向流通}}}}
*/func main() {// var a [10]intfor i := 0; i < 1000; i++ {go func(i int) { // go run -race test.go  检测数据访问冲突 rece conditionfor {fmt.Printf("Hello from"+"goroutine %d \n", i)// a[i]++// runtime.Gosched() // 很少用到}}(i)}time.Sleep(time.Minute)// fmt.Println(a)
}
  • channel.go
package mainimport ("fmt""time"
)/*channel{包含{goroutine <= channel => goroutine * n调度器}理论基础{communication Sequential Process(CSP模型)不要通过共享内存来通信,通过通信来共享内存}}
*/func worker(id int, c chan int) {for n := range c { // 接收完毕 关闭1// n, ok := <-c // 接收完毕 关闭2// if !ok {// 	break// }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 chanDemo() {// var c chan int // 只是定义 没有开辟内存空间 c == nilvar 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) // 新建一个大小为3的缓冲区go worker(0, c)c <- 'a'c <- 'b'c <- 'c'time.Sleep(time.Millisecond) //
}func channelClose() {// 永远是发送方来closec := make(chan int, 3) // 新建一个大小为3的缓冲区go worker(0, c)c <- 'a'c <- 'b'c <- 'c'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()
}
  • done.go
package mainimport ("fmt""sync"
)/*使用WaitGroup
*/func doWorker(id int, w worker) {for n := range w.in { // 接收完毕 关闭1fmt.Printf("Worker %d received %c \n", id, n)w.done()}
}type worker struct {in chan int// done chan bool// wg *sync.WaitGroupdone func()
}func createWorker(id int, wg *sync.WaitGroup) worker {w := worker{in:   make(chan int),done: func() { wg.Done() },}go doWorker(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' + iwg.Add(1)}for i, worker := range workers {worker.in <- 'A' + iwg.Add(1)}wg.Wait()// wait for all of them// for _, worker := range workers {// 	<-worker.done// }
}func main() {chanDemo()
}
  • select.go
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() // c1 and c2 == nilvar worker = createWorker(0)var values []int// 从启动程序过去的时间tm := time.After(10 * time.Second)// 每过多长时间tick := time.Tick(time.Second)for {// nil channel 有值的时候才会初始化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 n := <-c1:// fmt.Println("Received from c1:", n)// case n := <-c2:// fmt.Println("Received from c2:", n)// 非阻塞式从chan获取值// default:// fmt.Println("No value received")// 每次执行select 的时间 相邻两个请求时间的time outcase <-time.After(800 * time.Millisecond):fmt.Println("time out")// 反应系统的状态case <-tick:fmt.Println("queue len = ", len(values))// 总的时间来确定程序时常case <-tm:fmt.Println("bye")return}}}
  • atomic
package mainimport ("fmt""sync""time"
)type atomicInt struct {value intlock  sync.Mutex
}func (a *atomicInt) increment() {a.lock.Lock()defer a.lock.Unlock()a.value++
}func (a *atomicInt) get() int {a.lock.Lock()defer a.lock.Unlock()return a.value
}func main() {var a atomicInta.increment()go func() {a.increment()}()time.Sleep(time.Millisecond)fmt.Println(a.get())
}

 

  相关解决方案