Implementation of golang concurrent programming

Time:2020-11-20

go

The execution of the main function itself is a coroutine. When the go keyword is used, a new coroutine is created

channel

Channel pipe, used to pass signals between multiple coroutines

No cache pipeline

When writing to a bufferless channel, it blocks until a coprocessor reads the buffered channel

Blocking scenario:

  1. There is no data in the channel, but a read channel is performed.
  2. There is no data in the channel, and the data is written to the channel, but there is no coroutine reading.

To sum up, the read and write without cache channel must exist at the same time, and the read and write are in two different coprocesses


func main(){
  ch := make(chan int)
  
  go func(ch chan int){
    ch <-222
  }(ch)
  
  println(<-ch)
}

With buffer pipe

When there is a cache, data can be written to the channel and returned directly. When there is data in the cache, the data can be read from the channel and returned directly. At this time, the channel with cache will not be blocked

Blocking scenario:

  1. The cache of the channel has no data, but the read channel is executed.
  2. The cache of the channel is full, data is written to the channel, but there is no coroutine read.

To sum up, read and write with buffer channel must be in two different coprocesses

func main() {
  Ch: = make (Chan int, 1) // buffer pipes of length 1 also have buffer pipes
  ch <- 333
  go func(ch chan int) {
    println(<-ch)
  }(ch)
  ch <- 333
}

sync.Mutex And sync.RwMutex

sync.Mutex Concurrent lock, only one concurrent lock can be loaded at a time

sync.RwMutex Read and write locks. Multiple read locks and one write lock can be loaded at a time. When a write lock exists, the read lock and the write lock cannot be loaded

sync.WaitGroup

Blocking wait for all tasks to complete before continuing

Waitgroup is passed in no method, need to pass a pointer


func main() {
  var wg sync.WaitGroup
  ch := make(chan int, 1000)
  for i := 0; i < 1000; i++ {
    wg.Add(1)
    go doSomething(i, &wg, ch)
  }
  wg.Wait()
  fmt.Println("all done")
  for i := 0; i < 1000; i++ {
    dd := <-ch
    fmt.Println("from ch:"+strconv.Itoa(dd))
  }
}

func doSomething(index int, wg *sync.WaitGroup, ch chan int) {
  defer wg.Done()
  fmt.Println("start done:" + strconv.Itoa(index))
  //time.Sleep(20 * time.Millisecond)
  ch <- index
}

The above is the whole content of this article, I hope to help you in your study, and I hope you can support developeppaer more.