面向奶酪:用同步与互斥锁,讲“美食争夺”。

faceNL · · 982 次点击 · 开始浏览    置顶
这是一个创建于 的主题,其中的信息可能已经有所发展或是发生改变。

同步 突发奇想,想到之前学java的时候,看过一个抢票的列子,然后对线程有了个大概的了解。我也模仿一下,来讲一下goroutine。哈哈哈 goroutine 就是类似于 java中的线程,执行速度极快,不加个sleep,你完全看不到goroutine的输出。 我在下面代码 加了sleep等待1秒钟。 ```go func main() { const err = false ch := make(chan string, 2) //加个缓存,防止阻塞 var food = []string{"饼干", "可乐", "夹心饼", "奶酪", "雪碧", "火龙果", "冰镇西瓜", "火鸡面", "土司", "冰淇淋"} go func(ch <-chan string) { for c := range ch { fmt.Println("Mr.Cheese 抢到了 ", c) } }(ch) go func(ch <-chan string) { for c := range ch { fmt.Println("Mr.Potato 抢到了 ", c) } }(ch) for _, v := range food { ch <- v } close(ch) time.Sleep(1* time.Second) // 等待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),整个过程,互相争夺的过程。 互斥锁 一个没有互斥锁的列子 ```go 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,并没有换到自己心仪的食物,为了保证每个协程能换成自己的心仪的食物。如下 一个有互斥锁的列子 ```go func main() { mutex := sync.Mutex{} wg := wg.waitGroup() wg2 := wg.waitGroup() wa.add(1) wa2.add(3) food :=[]string {"西瓜","巧克力","蛋糕","土司","饼干"} go func() { //协程a mutex.Lock() food[0] = "哈密瓜" fmt.Println("协程A:我把西瓜换成了哈密瓜",food) mutex.Unlock() wg2.Done() }() go func() { //协程b mutex.Lock() food[0] = "火龙果" fmt.Println("协程B:我把西瓜换成了火龙果",food) mutex.Unlock() wg2.Done() }() go func() { //协程c mutex.Lock() food[0] = "榴莲" fmt.Println("协程C:我把西瓜换成了榴莲",food) mutex.Unlock() wg2.Done() }() time.Sleep(1e9) wg.Done() wg2.Wait() } --------------------------------- 输出结果: 协程A:我把西瓜换成了哈密瓜 [哈密瓜 巧克力 蛋糕 土司 饼干] 协程B:我把西瓜换成了火龙果 [火龙果 巧克力 蛋糕 土司 饼干] 协程C:我把西瓜换成了榴莲 [榴莲 巧克力 蛋糕 土司 饼干] ``` 锁能保证每个协程能够对数据修改,其它协程必须得等待,直到释放锁。其它协程抢占资源,执行Lock()到unlock的过程。 > 溜了 溜了~~

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

982 次点击  
加入收藏 微博
4 回复  |  直到 2019-05-20 21:40:02
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传