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

  • 相关阅读:
    LINQ/EF/Lambda 比较字符串日期时间大小
    WinForm RDLC SubReport Step by step
    centos7安装7-zip
    centos修改命令提示符颜色
    更换官方zabbix.repo为阿里云镜像
    利用shell脚本清理nginx日志
    docker
    centos 建立静态 IP 与 IP 地址丢失的解决办法
    构建lnmp高可用架构
    keepalived高可用
  • 原文地址:https://www.cnblogs.com/peterleee/p/13406047.html
Copyright © 2011-2022 走看看