同步
突发奇想,想到之前学java的时候,看过一个抢票的列子,然后对线程有了个大概的了解。我也模仿一下,来讲一下goroutine。哈哈哈
goroutine 就是类似于 java中的线程,执行速度极快,不加个sleep,你完全看不到goroutine的输出。
我在下面代码 加了sleep等待1秒钟。
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),整个过程,互相争夺的过程。
互斥锁
一个没有互斥锁的列子
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{}
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的过程。
溜了 溜了~~