简明笔记:用同步与互斥锁,讲“美食争夺”。

Posted 面向奶酪

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了简明笔记:用同步与互斥锁,讲“美食争夺”。相关的知识,希望对你有一定的参考价值。



同步


突发奇想,想到之前学java的时候,看过一个抢票的列子,然后对线程有了个大概的了解。我也模仿一下,来讲一下goroutine。哈哈哈


goroutine 就是类似于 java中的线程,执行速度极快,不加个sleep,你完全看不到goroutine的输出。

我在下面代码 加了sleep等待1秒钟。

func main() {
    const err =false
    ch := make(chan string,2) //加个缓存,防止阻塞
    var food = [] string{"饼干","可乐","夹心饼","奶酪","雪碧","火龙果","冰镇西瓜","火鸡面","土司","冰淇淋"}

    for _,v := range food{
        ch <- v
        go func(ch <- chan string) {
            c:= <-ch
            fmt.Println("Mr.Cheese 抢到了 ",c)
        }(ch)
        go func(ch <- chan string) {
            c := <-ch
            fmt.Println("Mr.Potato 抢到了 ",c)
        }(ch)
    }
    time.Sleep(1e9)  // 等待1秒!!!

}

--------------------------------------
输出结果:
Mr.Potato 抢到  饼干
Mr.Cheese 抢到  可乐
Mr.Potato 抢到  夹心饼
Mr.Potato 抢到  奶酪
Mr.Cheese 抢到  雪碧
Mr.Cheese 抢到  火龙果
Mr.Potato 抢到  冰镇西瓜
Mr.Potato 抢到  土司
Mr.Cheese 抢到  火鸡面
Mr.Cheese 抢到  冰淇淋

当ch<-v 写入数据时(可以写满2个,因为指定了缓存),此时是等待被goroutine中的读取(<-ch),整个过程,互相争夺的过程。


互斥锁

一个没有互斥锁的列子

func main() {
  food :=[]string {"西瓜","巧克力","蛋糕","土司","饼干"}
  go func() {
     food[0] = "哈密瓜"
     fmt.Println("我把西瓜换成了哈密瓜",food)
  }()
  go func() {
     food[0] = "火龙果"
     fmt.Println("我把西瓜换成了火龙果",food)
  }()
  go func() {
     food[0] = "榴莲"
     fmt.Println("我把西瓜换成了榴莲",food)
  }()
  time.Sleep(1e9)
}
------------------------------------------
输出结果:
协程B:我把西瓜换成了火龙果 [榴莲 巧克力 蛋糕 土司 饼干]
协程A:我把西瓜换成了哈密瓜 [榴莲 巧克力 蛋糕 土司 饼干]
协程C:我把西瓜换成了榴莲 [榴莲 巧克力 蛋糕 土司 饼干]

协程B和协程A,并没有换到自己心仪的食物,为了保证每个协程能换成自己的心仪的食物。如下

一个有互斥锁的列子

func main() {
  mutex := sync.Mutex{}

  food :=[]string {"西瓜","巧克力","蛋糕","土司","饼干"}

  go func() {      //协程a
     mutex.Lock()
     food[0] = "哈密瓜"
     fmt.Println("协程A:我把西瓜换成了哈密瓜",food)
     mutex.Unlock()
  }()
  go func() {     //协程b
     mutex.Lock()
     food[0] = "火龙果"
     fmt.Println("协程B:我把西瓜换成了火龙果",food)
     mutex.Unlock()
  }()
  go func() {    //协程c
     mutex.Lock()
     food[0] = "榴莲"
     fmt.Println("协程C:我把西瓜换成了榴莲",food)
     mutex.Unlock()
  }()
  time.Sleep(1e9)
}
---------------------------------
输出结果:
协程A:我把西瓜换成了哈密瓜 [哈密瓜 巧克力 蛋糕 土司 饼干]
协程B:我把西瓜换成了火龙果 [火龙果 巧克力 蛋糕 土司 饼干]
协程C:我把西瓜换成了榴莲 [榴莲 巧克力 蛋糕 土司 饼干]

锁能保证每个协程能够对数据修改,其它协程必须得等待,直到释放锁。其它协程抢占资源,执行Lock()到unlock的过程。





往期推荐:





长按关注"面向奶酪"





以上是关于简明笔记:用同步与互斥锁,讲“美食争夺”。的主要内容,如果未能解决你的问题,请参考以下文章

读写锁 与 互斥锁

再探 同步与互斥

再探 同步与互斥

ReentrantReadWriteLock场景应用

ucos实时操作系统学习笔记——任务间通信(互斥锁)

C#学习笔记---线程同步:互斥量信号量读写锁条件变量