用于同步时通道和mutex的区别

本文对比了Go语言中通道和Mutex同步机制的性能差异,通过实例展示了在高并发场景下,Mutex相较于通道能提供更好的性能表现。同时,介绍了通道的多重使用特性以及select语句在并发控制上的灵活性。

用于同步时通道和mutex的区别

通道是Go语言内建的特性之一,用来在程序内部传输数据,很容易用于同步目的。比如构建一个缓存为1的channel

c:=make(chan bool,1)
`,当需要独占的获得时,就可以<-c,而要释放时,执行c<-true

Mutex是sync包定义的一个类型,实现了互斥锁,定义了Lock()/Unlock()方法来获得/释放锁.

从功能角度看,使用通道同步和使用Mutex同步完全等价,但是从性能的角度看,差别很大,下面用一个例子来说明:

package main
import (
    "sync"
    "fmt"
    "time"
)
func f(){
    for{
        <-c
        if i==Max {
            wg.Done()
            c<-true
            return
        }else{
            i++
            c<-true
        }
    }
}
func g(){
    for{
        l.Lock()
        if i==Max{
            wg.Done()
            l.Unlock()
            return
        }else{
            i++
            l.Unlock()
        }
    }
}
var i int
var l sync.Mutex
var wg sync.WaitGroup
var c chan bool
var Max=500000
var Num=100
func init(){
    c=make(chan bool,1)
    c<-true
}
func main(){
    start:=time.Now()
    wg.Add(Num)
    for j:=0;j<Num;j++{
        go f()
    }
    wg.Wait()

    fmt.Println(time.Now().Sub(start),i,"channel")

    i=0
    start=time.Now()
    wg.Add(Num)

    for j:=0;j<Num;j++{
        go g()
    }
    wg.Wait()
    fmt.Println(time.Now().Sub(start),i,"sync.Mutex")
}




简单解释一下,在main()中,生成Num个goroutine,都是执行某个函数,然后等待这些goroutine返回,计时。f()和g()差不多,检测i是否等于Max,如果相等,那么返回;如果不等,那么增加i的值。不同的是f()使用通道作为同步,而g()使用Mutex作为同步。输出结果是:

62.648078ms 500000 channel

13.682324ms 500000 sync.Mutex


由此可以看出,作为同步原语使用时,Mutex性能要好于通道,同时也比通道使用简单,不需要如下面那样构建和初始化

c=make(chan bool,1)

c<-true

然而,通道作为语言的内建特性,即使仅仅用于同步,也有其读到之处。**select**语句允许在多个通道上等待,如:

data:=make([]string,5)
c:=make([]chan bool,5)

for i:=0;i<5;i++{
  c[i]=make(chan bool,1)
  c[i]<-true
}

在进过初始化后,我们就可以使用select语句来选择一个通道元素来读取

 
select {
  id:=0
  case <-c[0]:
  case <-c[1]:
    id=1
  case <-c[2]:
    id=2
  case <-c[3]:
    id=3
  case <-c[4]:
    id=4
  ...
  //访问data[id]
  c.[id]<-true
}

只要有一个元素可用,我们就不会在这里阻塞。这一点,Mutex无法实现

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值