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)
}

  

 

posted on 2022-01-07 15:14  孤灯引路人  阅读(82)  评论(0编辑  收藏  举报

导航