身为并发(concurrency)小能手的 Go 的重要特色
有了 channel 好像几乎不需要 lock (例如 mutex)了呢
2021/10/14 更新:Go 与 concurrency
虽然还有一些东西没介绍到,例如 closure(闭包),
但感觉还是赶快看看别的程序码会比较好玩一点XD
明天要爬山不知道有没有空好好来看 被选召的 Gopher 们,从零开始探索 Golang, Istio, K8s 数码微服务世界 系列 系列呢?
Go 的特点就是不需要特别 import 其他的模组,
内建的 go
这个关键字就能够开启类似 thread 的 goroutine,
并透过 Go Runtime Scheduler 排程使这些 goroutines 轮流跑。
至於 parallelism 要看硬体支援,也需要额外设定。
如果对於 concurrency(并发) / parallelism(并行) 的差别不熟悉可以参考 Concurrency is not parallelism 或 Google 图片。
只要在 function 前加一个 go
就可以开一个 goroutine(thread)
go f(x, y)
main 本身也是一个 goroutine
我个人觉得没有很好理解的观念,注意一开始不要把 channel 当成 buffer 理解。
看Go 的并发:Goroutine 与 Channel 介绍,以 「推入」「拉出」channel 来比喻,我觉得比 send / receive 还好懂一点。
ch := make(chan int) // create a channel
ch <- v // Send v to channel ch.
v := <-ch // Receive from ch, and
// assign value to v.
有一方在 send / receive 时,除非有另一方做 receive / send,不然就会 block(阻塞)在那
但我自己感觉只有 <- 才有 block 住?Channels的第20行的y拔掉後,main 就不会再等,直接 exit。
for i := range ch
直到 close(ch)
永远只有 sender 该做 close 的动作。
因为只有他知道什麽时候再也不会 send 任何东西了,而如果给关闭的 channel 送东西的话会导致 panic。
channel 不是档案不一定要 close
只有当 receiver 在跑回圈,例如印出 channel 接到的值,因为需要知道 sender 已经传完了所以需要 close。
select
当某个 goroutine 要拉取 channel 的资料而可能需要等待时,当下就 block 住而不能处理其他事情。
如果这是处理画面的 goroutine,就等於卡在那而不能有状态条或其他等等回馈。
使用 select,case <- ch
先试着拉,如果塞住就看别的 case,
直到有一个 channel 有送到值 或是 最後使用 default case。
select {
case <-ch: // Channel 中有资料执行此区域
fmt.Println("main goroutine finished")
return
default: // Channel 阻塞的话执行此区域
fmt.Println("WAITING...")
time.Sleep(500 * time.Millisecond)
}
select 有点像 switch,但每个 case 都是拉拉看某个 channel 资料是否另一方送来了。
推入 / 拉出的时间不对等时(例如有一方有比较复杂的运算),就会造成等待。
如果有 buffer,推入时就不用等到有人拉出才能继续推了;
只有当 buffer 满的时候会 block,也就是不能再推入了。
ch := make(chan int, 2)
<<: [day-23] Python-基本认识回圈!(Part .2)
上一篇我们的基因体时代-AI, Data和生物资讯 Day09-合成生物学与机器学习分享合成生物学领...
接下来要写自我介绍页, 自我介绍页使用 routes/web.php 里面的 Route::grou...
Abstract 我们前面已经讨论了相当多种取得Bean的方法,如:自动注入(@Autowired、...
因为专案刚好需要用到 所以纪录一下参数在哪边 纪录一下 使用Visual Studio Entity...
今天是最後一天啦!但学习的路还尚未中断!笔者今天想聊聊不一样的,看到标题应该可以猜到,我们今天要来聊...