go并发
1.go可以使用并发开启多个协程案例如下
package main
import (
"fmt"
"runtime"
"sync"
)
func main() {
runtime.GOMAXPROCS(2)
var wg sync.WaitGroup
wg.Add(2) //开启2个协程
fmt.Println("start gorouteings")
go func(){
defer wg.Done()
for count:=0; count <3;count++ {
for char:='a'; char < 'a'+26; char++ {
fmt.Printf("%c",char)
}
fmt.Println()
}
}()
go func(){
defer wg.Done()
for count:=0; count <3;count++ {
for char:='A'; char < 'A'+26; char++ {
fmt.Printf("%c",char)
}
fmt.Println()
}
}()
fmt.Println("end gorouteing")
wg.Wait() //为了防止协程没有执行完成,主协程关闭提前退出问题所以需要等待
}
备注:问题可以开启多个协程但是对资源这块有竞争关系案例如下
案例2
package main
import (
"fmt"
"runtime"
"sync"
)
var (
count int
wg sync.WaitGroup
)
func inCount(id int){
defer wg.Done()
runtime.Gosched()
for i:=0;i < 2; i++ {
value:= i
value++
count= value
}
}
func main(){
wg.Add(2)
go inCount(1)
go inCount(2)
wg.Wait()
fmt.Println(count)
}
备注:这个案例count为2说明有竞争关系因为协程在争夺资源所以为结果数值为2 解决办法加锁 案例3如下
package main
import (
"fmt"
"sync"
"sync/atomic"
)
var (
Count int64
wg sync.WaitGroup
)
func AddCount(){
wg.Done()
for i:=0;i<2;i++{
value := i
value++
atomic.AddInt64(&Count,1)
}
}
func main(){
wg.Add(2)
go AddCount()
go AddCount()
wg.Wait()
fmt.Println(Count)
}
备注:使用atomic包里面的方法因为是原子操作所以可以解决问题。这是第一种方法,还有第二种办法使用锁包 mutnx 给协程加锁代码如下
package main
import (
"fmt"
"sync"
)
var (
Count int
wg sync.WaitGroup
mutnx sync.Mutex
)
func intTotal(){
defer wg.Done()
mutnx.Lock()
for i:=0;i <2;i++ {
value:= Count
value++
Count = value
}
mutnx.Unlock()
}
func main(){
wg.Add(2)
go intTotal()
go intTotal()
wg.Wait()
fmt.Println(Count)
}