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

      

  • 相关阅读:
    Windows Server 2012配置开机启动项
    Windows Server 2019 SSH Server
    NOIP2017 senior A 模拟赛 7.7 T1 棋盘
    Noip 2015 senior 复赛 Day2 子串
    Noip 2015 senior复赛 题解
    Noip 2014 senior Day2 解方程(equation)
    Noip 2014 senior Day2 寻找道路(road)
    Noip 2014 senior Day2 无线网络发射器选址(wireless)
    Noip2014senior复赛 飞扬的小鸟
    Noip 2014 senior 复赛 联合权值(link)
  • 原文地址:https://www.cnblogs.com/mango1997/p/15524936.html
Copyright © 2011-2022 走看看