zoukankan      html  css  js  c++  java
  • GO语言学习笔记之协程和管道

    一、设置程序运行的CPU数量

    package main
    
    import (
    	"fmt"
    	"runtime"
    )
    
    func main() {
    	//获取当前系统CPU的数量
    	num:=runtime.NumCPU()
    	//设置num-1的cpu运行程序
    	//runtime.GOMAXPROCS(num-1)
    	fmt.Println(num)
    }
    

    二、使用互斥锁解决资源竞争的问题

    package main
    
    import (
    	"fmt"
    	"sync"
    	"time"
    )
    
    var(
    	mp =make(map[int]int,10)
    	lock sync.Mutex
    )
    
    func test(n int){
    	lock.Lock()
    	mp[n]=n
    	lock.Unlock()
    }
    
    func main() {
    	for i:=0;i<200;i++{
    		go test(i)
    	}
    	time.Sleep(time.Second*10)
    	for i:=0;i<200;i++{
    		fmt.Println(mp[i])
    	}
    }
    

    三、使用管道channel解决资源竞争的问题

    package main
    import ( "fmt"
    )
    func main() {
    	//演示一下管道的使用
    	//1. 创建一个可以存放 3 个 int 类型的管道
    	var intChan chan int
    	intChan = make(chan int, 3)
    	//2. 看看 intChan 是什么
    	fmt.Printf("intChan 的值=%v intChan 本身的地址=%p
    ", intChan, &intChan)
    	//3. 向管道写入数据
    	intChan<- 10
    	num := 211
    	intChan<- num
    	intChan<- 50
    	// intChan<- 98//注意点, 当我们给管写入数据时,不能超过其容量
    	//4. 看看管道的长度和 cap(容量)
    	fmt.Printf("channel len= %v cap=%v 
    ", len(intChan), cap(intChan)) // 3,
    	//5. 从管道中读取数据
    	var num2 int
    	num2 = <-intChan
    	fmt.Println("num2=", num2)
    	fmt.Printf("channel len= %v cap=%v 
    ", len(intChan), cap(intChan)) // 2, 3
    	//6. 在没有使用协程的情况下,如果我们的管道数据已经全部取出,再取就会报告 deadlock
    	//num3 := <-intChan
    	//num4 := <-intChan
    	//num5 := <-intChan
    	//fmt.Println("num3=", num3, "num4=", num4, "num5=", num5)
    }
    

    四、遍历管道

    package main
    
    import "fmt"
    
    func main() {
    	var arr chan int
    	arr=make(chan int,100)
    	for i:=1;i<101;i++{
    		arr<-i*5
    	}
    	close(arr)//遍历管道必须关闭,否则会报错deadlock
    	for v:=range arr{
    		fmt.Println(v)
    	}
    }
    

    五、channel使用注意事项和细节

    1) channel 可以声明为只读,或者只写性质

    2)使用 select 可以解决从管道取数据的阻塞问题

    package main
    import ( "fmt"
    	"time"
    )
    func main() {
    	//使用 select 可以解决从管道取数据的阻塞问题
    	//1.定义一个管道 10 个数据 int
    	intChan := make(chan int, 10)
    	for i := 0; i < 10; i++ {
    		intChan <- i
    	}
    	//2.定义一个管道 5 个数据 string
    	stringChan := make(chan string, 5)
    	for i := 0; i < 5; i++ {
    		stringChan <- "hello" + fmt.Sprintf("%d", i)
    	}
    	//传统的方法在遍历管道时,如果不关闭会阻塞而导致 deadlock
    	//问题,在实际开发中,可能我们不好确定什么关闭该管道. //可以使用 select 方式可以解决
    	//label:
    	for {
    		select {
    		//注意: 这里,如果 intChan 一直没有关闭,不会一直阻塞而 deadlock
    		//,会自动到下一个 case 匹配
    		case v := <-intChan:
    			fmt.Printf("从 intChan 读取的数据%d
    ", v)
    			time.Sleep(time.Second)
    		case v := <-stringChan:
    			fmt.Printf("从 stringChan 读取的数据%s
    ", v)
    			time.Sleep(time.Second)
    		default:
    			fmt.Printf("都取不到了,不玩了, 程序员可以加入逻辑
    ")
    			time.Sleep(time.Second)
    			return
    			//break label
    		}
    	}
    }
    

      

  • 相关阅读:
    fpga配置方式 .jic固化为ps模式
    fpga新建nios
    四轴飞行器飞行原理与双闭环PID控制
    fpga为什么要用nios 开发
    error A space is required after ',' comma-spacing
    vuex : Newline required at end of file but not found eol-last
    vue -Missing space before value for key 'path'vue.js解决空格报错
    visual studio 自动补全功能 以及代码没有颜色
    hadoop 伪分布模式环境搭建
    django框架-DRF工程之认证功能
  • 原文地址:https://www.cnblogs.com/mango1997/p/15524936.html
Copyright © 2011-2022 走看看