• Go并发


    1.WaitGroup等待当前运行的协程

    package main
    
    import (
    	"fmt"
    	"runtime"
    	"sync"
    )
    
    // Go语言的并发指的是能让某个函数独立于其他函数运行的能力
    // Go的调度器是在操作系统之上的
    //Go的并发同步模型来自一个叫做通信顺序进程(CSP)的东西
    //同步和传递数据的关键数据类型是通道
    func main() {
    	// 分配一个逻辑处理器给调度器使用
    	runtime.GOMAXPROCS(1)
    
    	//wg用来等待程序完成
    	//计数加2,表示要等待2个goroutine
    	var wg sync.WaitGroup
    	wg.Add(2)
    	fmt.Println("Start Goroutines")
    
    	//声明一个匿名函数,创建一个goroutine
    	go func() {
    		// 在函数退出时调用Done来同志main函数工作已经完成
    		defer wg.Done()
    		for count := 0; count < 3; count++ {
    			for char := 'a'; char < 'a'+26; char++ {
    				fmt.Printf("%c ", char)
    			}
    		}
    
    	}()
    
    	go func(){
    		defer wg.Done()
    		for count := 0; count < 3; count++ {
    			for char := 'A'; char < 'A'+26; char++ {
    				fmt.Printf("%c ", char)
    			}
    		}
    
    	}()
    
    	//等待goroutine结束
    	fmt.Println("Waiting To Finish")
    	wg.Wait()
    	fmt.Println("
    Terminating Program")
    }
    
    

    2.互斥锁
    在对共享资源进行计算的时候使用

    package main
    
    import (
    	"fmt"
    	"runtime"
    	"sync"
    )
    
    var (
    	// counter是所有goroutines都要增加其值的变量
    	counter int
    	// wg用来等待程序结束
    	wg sync.WaitGroup
    	// mutex用来定义一段代码临界区
    	mutex sync.Mutex
    )
    
    func main() {
    	// 计数为2,表示要等待两个goroutines
    	wg.Add(2)
    	go incCounter(1)
    	go incCounter(2)
    	wg.Wait()
    	fmt.Printf("Final Counter: %d
    ",counter)
    
    
    }
    
    func incCounter(id int){
    	defer wg.Done()
    	for count:=0;count<2;count++{
    		// 同一时刻只允许一个goroutine进入
    		// 这个是临界区
    		mutex.Lock()
    		{
    			//捕获counter的值
    			value:=counter
    			// 当前goroutines从线程退出,并放回到队列
    			runtime.Gosched()
    
    			//增加本地的value变量的值
    			value++
    			counter = value
    		}
    		mutex.Unlock()
    		//释放锁,允许其他正在等待的goroutine
    		//进入临界区
    	}
    }
    
    mutex.Lock(){}的花括号只是为了方便看,可以省略。
    

    3.无缓冲通道的使用

    package main
    
    import (
    	"fmt"
    	"sync"
    	"time"
    )
    
    //var wg sync.WaitGroup
    //
    //func main() {
    //	// 创建一个无缓冲的通道
    //	baton := make(chan int)
    //
    //	// 为最后一位跑步者将计数加1
    //	wg.Add(1)
    //	//第一位跑步者持有接力棒
    //	go Runner(baton)
    //	// 第一位选手接棒
    //	baton <- 1
    //	wg.Wait()
    //
    //}
    //
    //func Runner(baton chan int) {
    //	var newRunner int
    //	// 等待接力棒
    //	runner := <-baton
    //
    //	// 开始绕着跑道跑步
    //	fmt.Printf("Runner %d Running With Baton
    ", runner)
    //	if runner != 4 {
    //		newRunner = runner + 1
    //		fmt.Printf("Running %d To Rhe Line
    ", newRunner)
    //		go Runner(baton)
    //	}
    //	time.Sleep(1000 * time.Millisecond)
    //	//比赛结束了么
    //	if runner == 4 {
    //		fmt.Printf("Runner %d Finished,Race Over
    ", runner)
    //		defer wg.Done()
    //		return
    //	}
    //	fmt.Printf("Runner %d Exchange with Runner %d
    ", runner, newRunner)
    //	baton <- newRunner
    //}
    
    var wg sync.WaitGroup
    
    func main() {
    	//创建一个无缓冲的通道
    	baton:=make(chan int)
    	wg.Add(1) 
    	go Runner(baton) //第一位跑步者持有接力棒
    	baton<-1 //开始比赛
    	wg.Wait() //等待比赛结束
    }
    
    func Runner(baton chan int ){
    	var newRunner int
    	runner:=<-baton
    	fmt.Printf("第 %d 位选手开始跑
    ",runner)
    	if runner!=4{
    		newRunner = runner+1
    		fmt.Printf("第 %d 位选手准备
    ",runner)
    		go Runner(baton)
    
    	}
    	time.Sleep(1000*time.Millisecond)
    	if runner==4{
    		fmt.Printf("第%d位选手到达终点,比赛结束")
    		wg.Done() //完成的时候调用
    	}
    	//交给下一位
    	baton<-newRunner
    
    }
    

    来源:Go in Action

  • 相关阅读:
    STM32之系统滴答定时器
    MPU6050带字符驱动的i2c从设备驱动2
    MPU6050带字符驱动的i2c从设备驱动1
    基于μC/OS—III的CC1120驱动程序设计
    STM32串口DMA超时接收方法,可大大节约CPU时间
    neo1973 audio subsystem
    题解模板
    在 GoLang 中使用 jwt 进行认证
    (OperationNotSupportedInTransaction) Cannot create namespace test.application in multi-document transaction 错误的解决方法
    server selection timeout, current topology: { Type: ReplicaSetNoPrimary, Servers: Type: RSGhost 错误的解决方法
  • 原文地址:https://www.cnblogs.com/c-x-a/p/14067193.html
Copyright © 2020-2023  润新知