当前位置:网站首页>The method of freely controlling concurrency in the sync package in GO

The method of freely controlling concurrency in the sync package in GO

2022-08-05 00:32:00 Yisuyun

GO中syncPackage free methods for controlling concurrency

本篇内容主要讲解“GO中syncPackage free methods for controlling concurrency”,感兴趣的朋友不妨来看看.本文介绍的方法操作简单快捷,实用性强.下面就让小编来带大家学习“GO中syncPackage free methods for controlling concurrency”吧!

资源竞争

channel Often used for concurrent communication,To ensure concurrency safety,主要使用互斥锁.in the concurrent process,When a memory is multiple goroutine 同时访问时,There will be competition for resources.This piece of memory can also be called a shared resource.

Concurrency will inevitably lead to resource preemption for shared resources,If it is the statistics of a resource,It is very likely that the result will be wrong.To ensure that only one coroutine gets the resource and operates on it,Mutex locks can be introduced sync.Mutex.

sync.Mutex

互斥锁,Refers to concurrent time,Only one coroutine executes a certain piece of code at a time,Other coroutines can only continue to execute after waiting for the execution of the coroutine to complete.

var (sum int  mutex sync.Mutex)func add(i int){    mutex.Lock()    sum+=i    mute.Unlock()}

使用 mutex 加锁保护 sum+ =i 的代码片段,In this way, this fragment area cannot be accessed by multiple coroutines at the same time,When a coroutine enters the fragment area,Then other coroutines can only wait,This ensures the concurrency safety of critical sections.

sync.Mutex 只有 Lock()和 Unlock() 方法,它们是成对存在的,且Lock后一定要执行Unlock进行释放锁.所以可以使用 defer 语句释放锁,To ensure that the lock will be released.

func add(i int){    mutex.Lock()    defer mutex.Unlock()    sum += i}

sync.RWMutex

上面例子是对 sum 写操作时使用sync.Mutex 保证并发安全,When multiple coroutines perform read operations,Avoid reading data incorrectly due to concurrency,Mutexes can also be used sync.Mutex.

func getSum(){    mutex.Lock()    defer mutex.Unlock()    b:=sum    return b}

多个协程 goroutine The resource competition problem of simultaneous reading and writing is solved,还需要考虑性能问题,Each read or write to the shared resource is locked,It can also lead to low performance.

The following situations are encountered when multiple coroutines read and write concurrently:

  • Writes cannot be read at the same time,Dirty data is easy to read

  • A read cannot be written at the same time,Because it will lead to inconsistent results

  • Write while reading,Because the data does not change,无论多少个 goroutine Reads are all concurrency safe

使用读写锁 sync.RWMutex 优化代码:

var mutex sync.RWMutexfunc readSum() int {    mutex.RLock()    defer mutex.RUnlock()    b := sum    return b}

Read-write locks perform better than mutex locks.

sync.WaitGroup

In order to be able to monitor the execution of all coroutines,一旦所有的goroutine 都执行完成,The program should exit in time to save time and improve performance.通过使用 sync.WaitGroup 来解决.使用步骤如下:

  • 声明一个 sync.WaitGroup ,通过 add method to increment the counter value,There are several coroutines to calculate a few

  • Called after each coroutine ends Done 方法,The main thing is to decrement the counter1

  • 最后调用 Wait 方法一直等待,直到计数器为 0 时,All tracked coroutines are executed

func run() {    var wg sync.WaitGroup    wg.Add(100)    for i := 0; i < 100; i++ {        go func() {            defer wg.Done()            add(10)        }()    }    wg.Wait()}

通过 sync.WaitGroup 可以很好地跟踪协程.

sync.Once

sync.Once The effect is to make the code execute only once.Detailed usage is to call the method once.Do 方法,具体实现:

func main(){    var once sync.once    oneFunc := func(){        println("once func")    }    once.Do(oneFunc)}

sync.Once 适用于创建某个对象的单例、只加载一次的资源等只执行一次的场景.

sync.Cond

使用 sync.WaitGroup The main control is to wait for all coroutines to be executed,才最终完成.But when encountering the scene is,Only start by waiting for all conditions to be ready.sync.Cond It's like giving orders,It can be executed only if the notification executes all the coroutines,The point is that all coroutines need to wait for wakeup before they can start.

所以 sync.Cond Has the function of blocking coroutines and waking up coroutines.详细的用法:

  • 通过 sync.NewCond 函数生成一个 *sync.Cond,Used to block and wake up coroutines

  • 调用 cond.Wait() The method blocks the current coroutine to wait,需要注意调用 cond.Wait() method to be locked

  • 调用 cond.Broadcast() All coroutines are executed after that

func run() {    cond := sync.NewCond(&amp;sync.Mutex{})    var wg sync.WaitGroup    wg.Add(101)    for i := 0; i &lt; 100; i++ {        go func(num int) {            defer wg.Done()            fmt.Println(num, "number is awaiting......")            cond.L.Lock()            cond.Wait() //Wait for all coroutines to be ready to complete            fmt.Println(num, "号开始跑……")            cond.L.Unlock()        }(i)    }    // Wait for all coroutines to enter wait 状态    time.Sleep(2*time.Second)    go func() {        defer wg.Done()        // All ready to be done,开始        cond.Broadcast()    }()    // 防止函数提前返回退出    wg.Wait()}

到此,相信大家对“GO中syncPackage free methods for controlling concurrency”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

原网站

版权声明
本文为[Yisuyun]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/217/202208050008067271.html