Go basic concurrency security and locks

Sometimes there may be multiple goroutines operating a resource (critical section) at the same time in the Go code. In this case, static style (data static) will occur. Analogous to real life examples, there are intersections that are competed by cars in all directions; there is a toilet on a train that is competed by people in the carriage.
Example:

package main

import (
	"fmt"
	"sync"
)

var wy sync.WaitGroup

var x int

func add() {
    
    
	for i := 0; i < 50000; i++ {
    
    
		x += 1
	}
	wy.Done()
}

func main() {
    
    
	wy.Add(2)
	go add()
	go add()
	wy.Wait()
	fmt.Println(x)
}

Mutex Locks
Mutex locks are a commonly used method to control
access to shared resources. It can ensure that only one goroutine can access shared resources at the same time. Go language uses the Mutex type of the sync package to implement mutex locks. Use mutex locks to fix the problem of the above code:

package main

import (
	"fmt"
	"sync"
)

var wy sync.WaitGroup
var lock sync.Mutex

var x int

func add() {
    
    
	for i := 0; i < 50000; i++ {
    
    
		//加锁
		lock.Lock()
		x += 1
		//解锁
		lock.Unlock()
	}

	wy.Done()
}

func main() {
    
    
	wy.Add(2)
	go add()
	go add()
	wy.Wait()
	fmt.Println(x)
}

Using mutex locks can ensure that only one goroutine enters the critical area at the same time, while other goroutines are waiting for the lock; when the mutex lock is released, the waiting goroutine can acquire the lock and enter the critical area, and multiple goroutines are waiting for a lock at the same time At times, the wake-up strategy is random.
Read and write mutexes
mutexes are completely mutually exclusive, but there are many practical scenarios where there are more reads and less writes. When we read a resource concurrently and do not involve resource modification, there is no need to lock it. In this scenario, using a read-write lock is a better choice. The read-write lock uses the RWMutex type in the sync package in the Go language

There are two types of read-write locks: read locks and write locks. When a goroutine acquires a read lock, other goroutines will continue to acquire the lock if they acquire a read lock, and will wait if they acquire a write lock; when a goroutine acquires a write lock, other goroutines will either acquire a read lock or a write lock. wait.

package main

import (
	"fmt"
	"sync"
)

var wy sync.WaitGroup
var lock sync.Mutex
var rwlock sync.RWMutex

var x int

func add() {
    
    
	for i := 0; i < 10; i++ {
    
    
		//加写锁
		rwlock.Lock()
		x += 1
		//解写锁
		rwlock.Unlock()
	}
	wy.Done()
}

func read() {
    
    
	for i := 0; i < 100; i++ {
    
    
		//加读锁
		rwlock.RLock()
		fmt.Println(x)
		//解读锁
		rwlock.RUnlock()
	}
	wy.Done()
}

func main() {
    
    
	wy.Add(3)
	go read()
	go read()
	go add()
	wy.Wait()
}

Guess you like

Origin blog.csdn.net/weixin_44865158/article/details/115013566