您的位置:首页 > 财经 > 产业 > 三年疫情最后成了闹剧_网站设计的目的_大数据推广公司_电脑优化大师下载安装

三年疫情最后成了闹剧_网站设计的目的_大数据推广公司_电脑优化大师下载安装

2025/3/10 21:01:03 来源:https://blog.csdn.net/m0_66201040/article/details/143950292  浏览:    关键词:三年疫情最后成了闹剧_网站设计的目的_大数据推广公司_电脑优化大师下载安装
三年疫情最后成了闹剧_网站设计的目的_大数据推广公司_电脑优化大师下载安装

  好久没学习golang了,今天学习了一下协程。

文章目录

  • go关键字
  • 通道
  • 等待
  • 互斥锁
  • 选择器

go关键字

使用go关键字,再加一个函数名,就可以开启一个新的协程.

package mainimport ("fmt""time"
)func main() {go func() {fmt.Println("goroutine")}()fmt.Println("main")time.Sleep(time.Second)
}

通道

  通道是协程之间的通讯机制。通过<-运算符向通道写入或读取数据。
创建通道是make函数。从通道读数据时,如果通道没有数据,就会阻塞。
以下是一个简单的例子:

package mainimport ("fmt""time"
)func worker(i int, ch chan int) {for {fmt.Println("worker", i, "通道数据", <-ch)}
}
func main() {// RoutineDemo()ch := make(chan int)// 开始3个协程for i := 0; i < 3; i++ {go worker(i, ch)}// 向通道写入数据10次for i := 0; i < 10; i++ {ch <- itime.Sleep(time.Second)}
}

等待

  在Go语言中,可以使用WaitGroup等待一组协程执行完毕。
前面的例子里,用的是time.Sleep函数,让主协程等待子协程执行完毕。这种写法肯定是不行的,因为很难准确估计子协程执行需要的时间。
幸好go语言提供了WaitGroup,可以很方便地等待所有子协程执行完毕。

package mainimport ("fmt""math/rand/v2""sync""time"
)func work(i int, wg *sync.WaitGroup) {var n = time.Duration(rand.IntN(3))defer wg.Done()time.Sleep(time.Second * n)fmt.Println(i, "Hello World")
}func main() {wait := sync.WaitGroup{}for i := 0; i < 5; i++ {go work(i, &wait)wait.Add(1)}wait.Wait()fmt.Println("All Done")
}

互斥锁

  在Go语言中,可以使用sync.Mutex互斥锁来控制对共享资源的访问。
在下面的例子中,如果不适用互斥锁,自增的结果就会不正确。

package mainimport ("fmt""sync"
)var counter intfunc increment(group *sync.WaitGroup, locker *sync.Mutex) {locker.Lock()counter++group.Done()locker.Unlock()
}
func main() {var lock sync.Mutexvar wg sync.WaitGroupfor i := 0; i < 1000; i++ {wg.Add(1)go increment(&wg, &lock)}wg.Wait()fmt.Println(counter)
}

  去掉互斥锁,我得到的结果是991,而不是1000。

选择器

  Go语言中的select关键字可以用来监听通道上的数据流动。
当通道上有数据流入时,对应的case会被执行。如果没有数据流入,默认的代码会被执行。
比如说主协程可以监听多个通道,每个子协程向不同的通道写入数据。以下是一个简单的例子:

package mainimport ("fmt""time"
)func main() {ch1 := make(chan string)ch2 := make(chan string)go func() {for {time.Sleep(1 * time.Second)ch1 <- "hello"}}()go func() {for {time.Sleep(2 * time.Second)ch2 <- "world"}}()for {select {case msg1 := <-ch1:fmt.Println("msg1", msg1)case msg2 := <-ch2:fmt.Println("msg2", msg2)}}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com