lzh2nix / articles

用 issue 来管理个人博客
https://github.com/lzh2nix/articles
61 stars 13 forks source link

golang 强筋壮骨系列之 Concurrency(初级) #71

Open lzh2nix opened 4 years ago

lzh2nix commented 4 years ago

目录

Learning Go’s Concurrency Through Illustrations(2020.07.30) Data races in Go(Golang) and how to fix them(2020.07.30) Go’s append is not always thread safe(2020.07.30)

lzh2nix commented 4 years ago

看图学golang并发编程(2020.07.30)

原文: https://medium.com/@trevor4e/learning-gos-concurrency-through-illustrations-8c4aff603b3

图解golang并发编程,知识点还是那些知识点,bufferedChannel, unbufferedChannel以及channel的range操作,基本上都是basic部分的那些知识点。

myChan := make(chan string)

go func(){
 myChan <- “Message!”
}()

select {
 case msg := <- myChan:
  fmt.Println(msg)
 default:
  fmt.Println(“No Msg”)
}
<-time.After(time.Second * 1)
select {
 case msg := <- myChan:
  fmt.Println(msg)
 default:
  fmt.Println(“No Msg”)
}

关于 golang 并发可以详细的看下下面两个视频,都是go team出品: Go Concurrency Patterns

看这个视频,想起了当时学习erlang的日子,忘了当时是在书上看到的还是看了joe老爷子的视频,也是讲为啥erlang里要原生支持多线程,记得当时也是举了现实生活中的例子(每个人都是在并行的做自己的事情,然后有需要了通过mailbox进行交互)

concurrency patterns

Advanced Go Concurrency Patterns

deadlock detection race detection pnaic show the backtrace stack select statement to stop live system(recevive a close channel) for-select loop 善于用channel

也是第一次见 chan chan error 类型, service chan, reply chan

fetcher 超时这汇总case是不是用context处理更好?

lzh2nix commented 4 years ago

golang中的data race(2020.07.30)

原文: https://www.sohamkamani.com/blog/2018/02/18/golang-data-race-and-how-to-fix-it/

多线程的环境中处理数据竞争确实一个很难的问题,一般在c/c++中的都是通过不断加日志里看有没有数据竞争,在golang里直接可以使用自带的 race dectector. 在golang中加上 go run -race xxx.go就可以检测数据竞争的问题,在输出中也是有非常详细的信息:

func main() {
    fmt.Println(getNumber())
}

func getNumber() int {
    var i int
    go func() {
        i = 5
    }()

    return i
}

这里有两个变量都会访问i所以很容易造成数据竞争. 可以通过 go run -race main.go 进行检测:

0
==================
WARNING: DATA RACE
Write at 0x00c420086008 by goroutine 6: ---------------------->被 goroutine 6 写了数据
  main.getNumber.func1()
      /Users/soham/go/src/tmp/main.go:15 +0x3b

Previous read at 0x00c420086008 by main goroutine: ----------->被main goroutine 进行了读操作
  main.getNumber()
      /Users/soham/go/src/tmp/main.go:17 +0x8e
  main.main()
      /Users/soham/go/src/tmp/main.go:9 +0x33

Goroutine 6 (running) created at:-----------------------------> goroutine 6 是在那一行创建的
  main.getNumber()
      /Users/soham/go/src/tmp/main.go:14 +0x7d
  main.main()
      /Users/soham/go/src/tmp/main.go:9 +0x33
==================
Found 1 data race(s)
exit status 66

解决方式:

  1. 使用channel
  2. 使用mutex
lzh2nix commented 4 years ago

golang append是线程不安全的(2020.07.30)

原文: https://medium.com/@cep21/gos-append-is-not-always-thread-safe-a3034db7975

这里主要是受到slice的memory model的影响,append之后ptr指向的数组并不会立马复制(只有cap大于当前的cap之后才会分裂),所以可能会导致两个goroutine向同一个slice append的时候出现data race。这也完全不是bug,纯粹的语言特性。

这里作者通过

y := make([]string, 0, len(x)+2)
y = append(y, x...)

这样的方式去解决了,其实也可以通过copy的方式解决:

y := make([]string, len(x), cap(x))
copy(y, x)
y = append(y, "hello", "world")
lzh2nix commented 4 years ago

golang channel教程(2020.07.31)

原文: https://guzalexander.com/2013/12/06/golang-channels-tutorial.html

一篇比较好的介绍golang channel的教程,从变量定义到select statement, 基本上覆盖了所有channel相关的知识点。

channel相关的知识还是首推:

Go Concurrency Patterns Advanced Go Concurrency Patterns

两篇演讲超级精彩