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


    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()
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    通过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()
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63

    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 ........")
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    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 ........")
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    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 ........")
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    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)
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    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)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    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)	
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    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("停止计时器堵塞")
    	// }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    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{
    
    	}
    	
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
  • 相关阅读:
    javascript【格式化时间日期】
    MySql架构模式
    高云FPGA系列教程(7):ARM GPIO外部中断
    【国际化多语言方案】i18n / class google sheets v4 api 在线文档同步json
    6.01 定时任务,关闭超时订单
    Simple-BEV: 多传感器BEV感知真正重要的是什么?(斯坦福大学最新)
    1024程序员节背后的秘密:1024程序员节的前世今生
    史上最全的15个苹果手机输入法使用技巧,不看后悔三年
    逍遥自在学C语言 | 逻辑运算符
    SSL 证书过期巡检脚本 (Python 版)
  • 原文地址:https://blog.csdn.net/qq_42874635/article/details/126700282