专栏首页Golang开发Golang包——sync

Golang包——sync

sync.Mutex互斥锁

// Lock 用于锁住 m,如果 m 已经被加锁,则 Lock 将被阻塞,直到 m 被解锁。
func (m *Mutex) Lock()
// Unlock 用于解锁 m,如果 m 未加锁,则该操作会引发 panic。
func (m *Mutex) Unlock()

sync.RWMutex读写锁

1.它允许任意读操作同时进行 2.同一时刻,只允许有一个写操作进行 3.并且一个写操作被进行过程中,读操作的进行也是不被允许的 4.读写锁控制下的多个写操作之间都是互斥的 5.写操作与读操作之间也都是互斥的 6.多个读操作之间却不存在互斥关系 写操作的锁定和解锁

// Lock 将 rw 设置为写锁定状态,禁止其他例程读取或写入。
func (rw *RWMutex) Lock()
// Unlock 解除 rw 的写锁定状态,如果 rw 未被写锁定,则该操作会引发 panic。
func (rw *RWMutex) Unlock()

读操作的锁定和解锁

// RLock 将 rw 设置为读锁定状态,禁止其他例程写入,但可以读取。
func (rw *RWMutex) RLock()
// Runlock 解除 rw 的读锁定状态,如果 rw 未被读锁定,则该操作会引发 panic。
func (rw *RWMutex) RUnlock()

注意:

写解锁在进行的时候会试图唤醒所有因欲进行读锁定而被阻塞的Goroutine. 读解锁在进行的时候只会在已无任何读锁定的情况下试图唤醒一个因欲进行写锁定而被阻塞的Goroutine 若对一个未被写锁定的读写锁进行写解锁,会引起一个运行时的恐慌 而对一个未被读锁定的读写锁进行读解锁却不会如此`

sync.WaitGroup

sync包中的WaitGroup实现了一个类似任务队列的结构,你可以向队列中加入任务,任务完成后就把任务从队列中移除,如果队列中的任务没有全部完成,队列就会触发阻塞以阻止程序继续运行。WaitGroup主要有以下三个方法

// 计数器增加 delta,delta 可以是负数。
func (wg *WaitGroup) Add(delta int)
// 计数器减少 1
func (wg *WaitGroup) Done()
// 等待直到计数器归零。如果计数器小于 0,则该操作会引发 panic。
func (wg *WaitGroup) Wait()

add 会给WaitGroup的counter加1,done会给WaitGroup的counter减1,当WaitGroup的counter的是0 则解除阻塞,否则一定要等任务都执行完毕后再继续执行接下来的操作。

import (
    "fmt"
    "math/rand"
    "sync"
    "time"
)

func work(name string,workTime time.Duration,sysGroup *sync.WaitGroup){
    defer sysGroup.Done()
    fmt.Printf("%s start work\n",name)
    time.Sleep(time.Second*workTime)
    fmt.Printf("After %d sec %s finid work\n",workTime,name)
}

func main() {
    var sysGroup sync.WaitGroup
    for i :=0;i<3;i++{
        sysGroup.Add(1)
        go work(fmt.Sprintf("Worker-%d",i), time.Duration(rand.Intn(10)),&sysGroup)
    }
    sysGroup.Wait()
    fmt.Printf("all people finish work\n")
}

sync.Once

// 多次调用仅执行一次指定的函数 f
func (o *Once) Do(f func())

例的fooOnce函数只执行一次打印。

func fooOnce(){
    fmt.Println("只会执行一次")
}
func main() {
    var once sync.Once
    done := make(chan int)
    for i := 0; i < 10; i++ {
        go func(index int) {
            once.Do(fooOnce)
            done <- index
        }(i)
    }
    for i := 0; i < 10; i++ {
        fmt.Println("接手到的数据",<-done)
    }
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • zookeeper(3)——watcher

    针对每个节点的操作,都会有一个监督者 watcher。 当监控的某个对象znode发生了变化,就会触发watcher事件 zk中的watch是一次性的,触发...

    羊羽shine
  • Python基础(15)——正则表达式

    re.match(正则表达式,要匹配的字符串),匹配出以字符串的起始位置开始匹配正则表达式,如果匹配,返回匹配对象(Match Object),否则返回None...

    羊羽shine
  • Golang——WebSocket

    拉模式的缺点 数据更新频率低,则大多数的请求是无效的 在线用户数量多,则服务端的查询负载高。 定时查询拉取,无法满足时效性要求 推送模式 尽在数据更新才推...

    羊羽shine
  • Go 语言并发编程系列(十三)—— sync 包系列:sync.WaitGroup 和 sync.Once

    在介绍通道的时候,如果启用了多个子协程,我们是这样实现主协程等待子协程执行完毕并退出的:声明一个和子协程数量一致的通道数组,然后为每个子协程分配一个通道元素,在...

    学院君
  • Golang并发的次优选择:sync包

    我们都知道Golang并发优选channel,但channel不是万能的,Golang为我们提供了另一种选择:sync。通过这篇文章,你会了解sync包最基础、...

    大彬
  • IE下尚未实现错误的原因

         IE下JS执行,提示“尚未实现”的错误,在firebug中没有任何错误提示。打开IE就遇到该死的“尚未实现错误”,根据IE中提示的位置找过去也没有发现...

    大江小浪
  • SAP Spartacus page-slot.component.html

    Jerry Wang
  • python多线程获取子线程任务返回值

    程序员同行者
  • .NET Remoting 体系结构 之 信道的功能和配置 (一)

      信道用于.NET 客户端和服务器之间的通信。.NET Framework 4 发布的信道类使用 TCP 、HTTP 或IPC 进行通信。我们可以为其他的协议...

    DougWang
  • Nginx基于TCP/UDP端口的四层负载均衡(stream模块)配置梳理

    通过我们会用Nginx的upstream做基于http/https端口的7层负载均衡,由于Nginx老版本不支持tcp协议,所以基于tcp/udp端口的四层负载...

    洗尽了浮华

扫码关注云+社区

领取腾讯云代金券