Go并发编程 | 青训营笔记

84 阅读2分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的的第5篇笔记

总结go中并发的支持,包括goroutine和channel等,后续附上youtube上关于并发与并行的区别。

Go并发

并发

goroutine

  • Go runtime管理得轻量级线程

  • goroutine在相同的地址空间中运行,因此访问共享内存时需要同步

    • sync以及其他方法

语法

  • go funcName(*args)

channel

  • 带类型的管道

  • 默认情况下,发送和接收操作在另一端准备好之前都会阻塞

    • goroutine可以在没有显式的锁或竞态变量的情况下进行同步
  • 带缓冲的channel,当信道的缓冲区填满后,向其发送数据时才会阻塞。当缓冲区为空时,接受方会阻塞。

语法

  • 创建make(chan int),或make(chan int, size)

    • 使用前必须创建
  • 发送ch <- v

  • 接收v:=<-ch

  • 关闭close(ch)

    • 只能由发送者关闭,非必要无需关闭

chan的类型

 var c chan int
 c = make(chan int, 10)
 ​
 go func(c chan int) {
  for i :=0; i<10; i++ {
      c <- i
  }
  // 如果不关闭,下方循环则不会终止
  // 程序会抛出死锁error
  defer close(c)
 }(c)
 ​
 for i := range(c) {
  println(i)
 }

Select

  • 一个goroutine可以等待多个通信操作
  • select会阻塞到某个分支可以继续执行为止,若多个分支准备就绪则会随机选择
  • 可以设置default分支
 // 两个channel,第二发消息时返回
 func fibonacci(c, quit chan int) {
     x, y := 0, 1
     for {
         select {
         case c <- x:
             x, y = y, x+y
         case <-quit:
             fmt.Println("quit")
             return
         }
     }
 }

channel适用于goroutine之间通信

sync.Mutex

  • 用于手动锁定来同步
  • Lock/Unlock
  • 使用defer来确保解锁

典型实践

  • 创建一个带锁的结构体
  • 操作结构体的时候先获取锁
 // SafeCounter is safe to use concurrently.
 type SafeCounter struct {
     mu sync.Mutex
     v  map[string]int
 }
 ​
 // Inc increments the counter for the given key.
 func (c *SafeCounter) Inc(key string) {
     c.mu.Lock()
     // Lock so only one goroutine at a time can access the map c.v.
     c.v[key]++
     c.mu.Unlock()
 }
 ​
 // Value returns the current value of the counter for the given key.
 func (c *SafeCounter) Value(key string) int {
     c.mu.Lock()
     // Lock so only one goroutine at a time can access the map c.v.
     defer c.mu.Unlock()
     return c.v[key]
 }
 ​
 func main() {
     c := SafeCounter{v: make(map[string]int)}
     for i := 0; i < 1000; i++ {
         go c.Inc("somekey")
     }
 ​
     time.Sleep(time.Second)
     fmt.Println(c.Value("somekey"))
 }

并发

Concurrency (computer science) - Wikipedia

In computer science, concurrency is the ability of different parts or units of a program, algorithm, or problem to be executed out-of-order or in partial order, without affecting the final outcome. This allows for parallel execution of the concurrent units, which can significantly improve overall speed of the execution in multi-processor and multi-core systems. In more technical terms, concurrency refers to the decomposability of a program, algorithm, or problem into order-independent or partially-ordered components or units of computation.

Google I/O 2012 - Go Concurrency Patterns - YouTube

concurrency is the compostion of independently executing computations.

并发是一些互不干扰的执行的计算任务的组合

并发是一种组织软件的方式,尤其是一种和真实世界交互时写出清晰代码的方式。

并发

Concurrency is not Parallelism by Rob Pike - YouTube

concurrency is about dealing a lot of things at once

parallelism is about doing a lot of things at once

concurrency is about structure ?

parallelism is about execution parallelism

并发模型可以将程序组织程独立的单元,但单元间需要通信支持

Communicating sequential processes (acm.org)