当前位置: 首页 > 工具软件 > Fish Sync > 使用案例 >

go中并发之waitgroup、runtime、sync、time

慕俊迈
2023-12-01

WaitGroup,主要用于协程同步执行

package main

import (
	"fmt"
	"sync"
)
 
var wg sync.WaitGroup

func Print(i int){
	defer wg.Done() // 等价于wg.Add(-1)
	fmt.Println("简单打印 ",i)
}
 

func main() {
	for i := 0; i < 10; i++ {
		go Print(i)
		wg.Add(1)
	}
	wg.Wait()
}

通过waitgroup顺序打印三个携程: cat dog fish

package main

import (
	"fmt"
	"sync"
	"time"
)

func Cat(catH, fishH chan int, wg *sync.WaitGroup){
	wg.Add(1)
	go func(){
		for {
			fmt.Println("my is cat........")
			catH <- 1
			// 堵塞
			<-fishH

		}
		// wg.Done()
	}()
}

func Dog(dogH, catH chan int, wg *sync.WaitGroup){
	wg.Add(1)
	go func(){
		for {
			<- catH
			fmt.Println("my is dog........")
			dogH <- 1

		}
		// wg.Done()
	}()
}

func Fish(dogH, fishH chan int, wg *sync.WaitGroup){
	wg.Add(1)
	go func(){
		for {
			<- dogH
			fmt.Println("my is fish........")
			time.Sleep(time.Second*2)
			fishH <- 1
			

		}
		// wg.Done()
	}()
}

func main() {
	catH := make(chan int)
	dogH := make(chan int)
	fishH := make(chan int)

	// 创建一个携程组
	wg := &sync.WaitGroup{}
	Cat(catH,fishH,wg)
	Dog(dogH,catH,wg)
	Fish(dogH,fishH,wg)

	wg.Wait()
}

runtime

runtime.Gosched()让出cpu时间片,重新等待安排任务

package main

import (
	"fmt"
	"runtime"
)

func Show(){
	for i := 0; i < 3; i++ {
		fmt.Println("my is show ......")
	}
	
}


func main() {
	go Show()

	// 主携程
	for i := 0; i < 3; i++ {
		runtime.Gosched()
		fmt.Println("my is main ....")
	}

	fmt.Println("end ........")
}

runtime.Goexit()退出当前携程

package main

import (
	"fmt"
	"runtime"
	"time"
)

func Show(){
	for i := 0; i < 10; i++ {
		fmt.Println("i is ", i)
		if i >= 5{
			fmt.Println("退出携程......")
			runtime.Goexit()
		}		
	}
}


func main() {
	go Show()
	// 主携程
	time.Sleep(2 * time.Second)
	fmt.Println("end ........")
}

runtime.GOMAXPROCS设置最大cpu核心数

package main

import (
	"fmt"
	"runtime"
	"time"
)

func Show01(){
	for i := 0; i < 10; i++ {
		fmt.Println("my is show01 ", i)		
	}
}

func Show02(){
	for i := 0; i < 10; i++ {
		fmt.Println("my is show02 ", i)		
	}
}

func main() {
	fmt.Println("本机cpu个数是:", runtime.NumCPU())
	// 设置使用cpu个数
	runtime.GOMAXPROCS(2)
	go Show01()
	go Show02()
	// 主携程
	time.Sleep(1 * time.Second)
	fmt.Println("end ........")
}

sync

sync.Mutex互斥锁

package main

import (
	"fmt"
	"time"
	"sync"
)

var num int = 100

var lock sync.Mutex

func FuncAdd(){
	lock.Lock()
	num += 1
	lock.Unlock()
}

func FuncSub(){
	lock.Lock()
	num -= 1
	lock.Unlock()
}
func main() {
	for i := 0; i < 100; i++ {
		go FuncAdd()
		go FuncSub()
	}
	time.Sleep(time.Second*3)
	fmt.Println("num is ", num)
}

sync.atomic原子操作

package main

import (
	"fmt"
	"time"
	"sync/atomic"
)
var i int32 = 100

// atomic原子操作 和python的原理一样 乐观锁
func funcAdd(){
	atomic.AddInt32(&i, 1)
}

func FuncSub(){
	atomic.AddInt32(&i, -1)
}

func main() {
	for i := 0; i < 100; i++ {
		go funcAdd()
		go FuncSub()
	}
	time.Sleep(time.Second*2)
	fmt.Printf("i: %v\n", i)
}
package main

import (
	"fmt"
	"sync/atomic"
)
func atomic_read_store(){
	var i int32 = 100
	atomic.LoadInt32(&i) // read
	fmt.Printf("i: %v\n", i)

	atomic.StoreInt32(&i, 200) // write
	fmt.Printf("i: %v\n", i)
}

func main() {
	atomic_read_store()
	// cas 将200变为300,如果修改失败返回false,乐观锁
	// atomic.AddInt底层用的就是cas
	var i int32 = 200
	atomic.CompareAndSwapInt32(&i, 200, 300)
	fmt.Printf("i: %v\n", i)	
}

time

time.NewTimer定时阻塞

package main

import (
	"fmt"
	"time"
)

func main() {
	t := time.NewTimer(time.Second * 2)
	fmt.Printf("time.Now(): %v\n", time.Now())

	// 重新设置阻塞时间
	t.Reset(time.Second*5)

	// 阻塞两秒
	t1 := <-t.C
	fmt.Printf("t1: %v\n", t1)

	// 阻塞两秒
	t2 := <-time.After(time.Second*2)
	fmt.Printf("t2: %v\n", t2)

	// 停止定时器
	// b := t.Stop()
	// if b {
	// 	fmt.Println("停止计时器堵塞")
	// }
}

time.NewTicker定时器

package main

import (
	"fmt"
	"time"
)

func main() {
	// t := time.NewTicker(time.Second)
	// for _ = range t.C{
	// 	fmt.Println("定时器。。。。。。")
	// }

	c := make(chan int)
	
	t := time.NewTicker(time.Second*2)

	go func() {
		for _ = range t.C{
			select {
				case c <-1:
				case c <-2:
				case c <-3:
			}
		}
	}()
	

	go func() {
		for v := range c{
			fmt.Printf("v: %v\n", v)
		}
	}()

	select{

	}
	
}

 类似资料: