zoukankan      html  css  js  c++  java
  • Golang 之sync包应用

    sync.Mutex

    保证共享资源的互斥访问

    mutex := &sync.Mutex{}
    mutex.Lock()
    // Update共享变量 (比如切片,结构体指针等)
    mutex.Unlock()

    sync.RWMutex

    读写互斥锁,可以对读加锁

    mutex := &sync.RWMutex{}
    mutex.Lock()
    // Update 共享变量
    mutex.Unlock()
    
    mutex.RLock()
    // Read 共享变量
    mutex.RUnlock()

    sync.WaitGroup

    使用Add()添加计数,Done()减掉一个计数,计数不为0, 阻塞Wait()的运行

    将数组每个值取平方,最后求所有的值的和,可以开数组大小的协程,用sync控制所有的协程都计算完成

    package main
    
    import (
        "fmt"
        "sync"
    )
    
    func opera(a int, taskres chan int, wg *sync.WaitGroup) {
        taskres <- a * a
        wg.Done()
    }
    func main() {
        a := []int{3, 5, 4, 7, 3, 8, 1}
        taskres := make(chan int, len(a))
        var wg sync.WaitGroup
        for _, v := range a {
            wg.Add(1)
            go opera(v, taskres, &wg)
        }
        wg.Wait()
        close(taskres)
        var result int = 0
        //range只能for关闭了的channel
        for i := range taskres {
            result += i
        }
        fmt.Println(result)
    }

    sync.Map

    sync.Pool

    sync.Once

    保证一个函数仅被执行一次

    once := &sync.Once{}
    for i := 0; i < 4; i++ {
        i := i
        go func() {
            once.Do(func() {
                fmt.Printf("first %d
    ", i)
            })
        }()
    }

    sync.Cond

    用于goroutine之间的协作,用于协程的挂起和唤醒。

    避免轮训空等,待着就好,wait别人signal你

    func main() {
        cond := sync.NewCond(new(sync.Mutex))
        condition := 0
    
        // Consumer
        go func() {
            for {
                cond.L.Lock()
                for condition == 0 {
                    cond.Wait()
                }
                condition--
                fmt.Printf("Consumer: %d
    ", condition)
                cond.Signal()
                cond.L.Unlock()
            }
        }()
    
        // Producer
        for {
            time.Sleep(time.Second)
            cond.L.Lock()
            for condition == 3 {
                cond.Wait()
            }
            condition++
            fmt.Printf("Producer: %d
    ", condition)
            cond.Signal()
            cond.L.Unlock()
        }
    }
    输出:
    Producer: 1
    Consumer: 0
    Producer: 1
    Consumer: 0
    Producer: 1
    Consumer: 0
    Producer: 1
    Consumer: 0
    Producer: 1
    Consumer: 0

  • 相关阅读:
    MQTT TLS 加密传输
    python多进程并发redis
    各种消息队列的特点
    mqtt异步publish方法
    Numpy API Analysis
    Karma install steps for unit test of Angular JS app
    reinstall bower command
    Simulate getter in JavaScript by valueOf and toString method
    How to: Raise and Consume Events
    获取对象的类型信息 (JavaScript)
  • 原文地址:https://www.cnblogs.com/peterleee/p/13406047.html
Copyright © 2011-2022 走看看