Implementation of golang concurrent programming
- 2020-09-16 07:30:39
- OfStack
go
The execution of the main function is itself a coroutine, and when the go keyword is used, a new coroutine is created
channel
The channel pipe is used to transmit signals between multiple coroutines
Cacheless pipe
When writing to an unbuffered channel, it blocks 1 until some coroutine reads the buffered channel
Blocking scenario:
There is no data in a channel, but a read channel is executed. There is no data in the channel. It writes data to the channel, but no coroutine reads it.To sum up, the reads and writes of the non-cached channel must exist simultaneously and in two different coroutines
func main(){
ch := make(chan int)
go func(ch chan int){
ch <-222
}(ch)
println(<-ch)
}
Buffered pipe
If there is cache, you can write data to the channel and return it directly. If there is cache, you can read data from the channel and return it directly. In this case, the cached channel will not block
Blocking scenario:
The channel caches no data, but executes a read channel. The channel cache is full and writes to the channel, but there is no coroutine read.In summary, buffer channel reads and writes must be in two different coroutines
func main() {
ch := make(chan int, 1) // Length of 1 Buffer pipes are also buffer pipes
ch <- 333
go func(ch chan int) {
println(<-ch)
}(ch)
ch <- 333
}
sync. Mutex and sync. RwMutex
sync. Mutex concurrent locks, only one concurrent lock can be loaded once
sync.RwMutex read-write lock, multiple read locks and one write lock can be loaded once. The read and write locks can no longer be loaded while the write lock exists
sync.WaitGroup
Blocking waits for all tasks to complete before continuing
WaitGroup is passed in a nonmethod. You 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
}