学习golang(day 8)- 协程、通道、WaitGroup、Mutex、Select、Atomic 2022-05-22 15:41:00 编程 golang 暂无评论 360 次阅读 2711字 修改时间:2022-05-22 21:30:26 #协程 Goroutine 协程类似于线程,但是比线程更轻量化,golang使用协程非常简单,只需在调用的函数前加上 go 关键字 **示例** ```go func show(message string) { for i := 0; i < 5; i++ { fmt.Println(message) time.Sleep(time.Millisecond * 100) } } func main() { // 类似于创建一个新的线程并发执行 go show("golang") go show("java") time.Sleep(time.Millisecond * 2000) fmt.Println("end.....") // 主函数退出后,协程就结束了 } ``` ------------ #通道 Channel 通道(channel)的作用是在协程(goroutine)之间共享数据。 通道有两种类型,有缓存和无缓存,无缓存是同步阻塞的,有缓存是异步的。 通道使用 make 函数创建 **示例** ```go // 无缓存通道,如果声明有缓存,需要在后面知道通道长度 var Values = make(chan int) func send() { rand.Seed(time.Now().UnixNano()) value := rand.Intn(10) // 向通道中写入一个随机数 Values <- value } func main() { // 关闭通道 defer close(Values) go send() fmt.Println("wait...") // 从通道中取出 value := <-Values fmt.Println(value) fmt.Println("end...") } ``` ------------ #协程同步 WaitGroup 如果需要两个协程之间需要相互等待,实现同步效果,可以使用 WaitGroup 来实现 类似于 java 中的 CountDownLatch **示例**. ```go var wp sync.WaitGroup func showMsg(i int) { fmt.Println(i) // down -1 defer wp.Done() } func main() { for i := 0; i < 10; i++ { go showMsg(i) wp.Add(1) } // 主线程需要等待所有协程执行完后再执行 wp.Wait() fmt.Println("主线程执行完") } ``` ------------ #并发编程 runtime 包 - runtime.Gosched() : 让出cup时间片 - runtime.Goexit() : 退出协程 - runtime.GOMAXPROCS(4) :设置最大线程数 ------------ #线程同步 Mutex 线程同步,互斥锁,类型于 Java 中的 Synchronized 同步锁 **示例** ```go var wg sync.WaitGroup var lock sync.Mutex var i = 100 func add() { lock.Lock() i++ fmt.Println("i++:", i) lock.Unlock() wg.Done() } func sub() { lock.Lock() i-- fmt.Println("i--:", i) lock.Unlock() wg.Done() } func main() { for i := 0; i < 100; i++ { wg.Add(1) go add() wg.Add(1) go sub() } wg.Wait() fmt.Println(i) } ``` ------------ #Select Select的语法结构类似 switch,处理异步IO操作,select 会监听case语句的channel的读写操作 **示例** ```go var chanInt = make(chan int) var chanChar = make(chan string) func main() { go func() { chanInt <- 100 chanChar <- "hello" }() for { select { case r := <-chanInt: fmt.Println(r) case r := <-chanChar: fmt.Println(r) default: fmt.Println("default") } time.Sleep(time.Second) } } ``` ------------ #Atomic 原子操作 和上面的互斥锁 Mutex 类似,在sync 包下的 atomic 原子操作 **示例** ```go var i int32 = 100 func add() { atomic.AddInt32(&i, 1) } func sub() { atomic.AddInt32(&i, -1) } func main() { for i := 0; i < 1000; i++ { go add() go sub() } time.Sleep(time.Second * 1) fmt.Println(i) } ``` 标签: golang
评论已关闭