• go的一些实现(关于channel循环打印,限流等等)


    go如何实现深拷贝?

    • 序列化和反序列化
    import (
    	"bytes"
    	"encoding/gob"
    	"fmt"
    )
    
    
    func deepCopy(dst, src interface{}) error {
    	var buf bytes.Buffer
    	if err := gob.NewEncoder(&buf).Encode(src); err != nil {
    		return err
    	}
    	return gob.NewDecoder(bytes.NewBuffer(buf.Bytes())).Decode(dst)
    }
    

    两个协程交替打印奇偶数

    //两个协程交替打印奇偶数
    
    func main(){
    	flagChan:=make(chan struct{}) //无缓冲chan
    
    	go func() {
    		for i:=1;i<=10;i++{
    			flagChan<- struct{}{}
    			if i&1==1{
    				fmt.Println("goroutine one:",i)
    			}
    		}
    	}()
    
    
    	go func() {
    		for i:=1;i<=10;i++{
    			<-flagChan
    			if i&1==0{
    				fmt.Println("gorroutine two:",i)
    			}
    		}
    	}()
    
       time.Sleep(3*time.Second)
    }
    

    两个协程循环打印字母和数字

    //两个协程轮流打印数字和字母  A 1 B 2 C 3 .... Z 26
    
    
    func main(){
    	Buffer() //有缓冲的方式
    	NoBuffer() //无缓冲的方式
    }
    
    
    //有缓冲区的chan循环打印.
    
    func Buffer(){
    	strChan:=make(chan struct{},1)
    	numChan:=make(chan struct{},1)
    
    	//先向numChan中放入作为开启
    	numChan<- struct{}{}
    
    	go func(){
    		for i:='A';i<='Z';i++{
    			<-numChan //读取之后才能继续
    			fmt.Printf("%v ",string(i))
    			strChan<- struct{}{}
    		}
    	}()
    
    	go func() {
    		for i:=1;i<=26;i++{
    			<-strChan
    			fmt.Printf("%v ",i)
    			numChan<- struct{}{} //通知数字打印完毕
    		}
    	}()
    
    	time.Sleep(3*time.Second)
    }
    
    
    
    //无缓冲的chan实现方式
    func NoBuffer(){
    	//
    	strChan:=make(chan struct{})
    	numChan:=make(chan struct{})
    
    	go func(){
    		for i:='A';i<='Z';i++{
    			fmt.Printf("%v ",string(i))
    			strChan<- struct{}{}
    			<-numChan //读取之后才能继续
    		}
    	}()
    
    	go func() {
    		for i:=1;i<=26;i++{
    			<-strChan
    			fmt.Printf("%v ",i)
    			numChan<- struct{}{} //通知数字打印完毕
    		}
    	}()
    
    	time.Sleep(3*time.Second)
    }
    
    

    N个协程循环打印1-100

    //N个协程交替打印1-100
    const NUM = 5  //假设5个协程交替打印
    
    func main(){
    
    	exitChan:=make(chan int,1) //退出的标识
    	chanNums:=make([]chan int,0)  //chan数组 ,开启多个协程哪个对应的chan到达则可以运行
    	res:=1 //全局res,因为交替打印,多协程操作也不需要加锁
    	index:=0 //协程标识,到达NUM重新归零
    
    	for i:=0;i<NUM;i++{  //初始化对应的chan
    		chanNums = append(chanNums,make(chan int,1))
    	}
    
    
    	for i:=0;i<NUM;i++{
    		go func(i int) { //开启NUM个协程
    			for { //循环打印
    				<-chanNums[i] //对应的chan存在数据才打印
    				if res>100{ //越界退出
    					exitChan<-1
    					break
    				}
    				fmt.Println("goroutine",i, "res:",res)
    				res++
    
    				index = (index+1)%NUM  //5个协程index为0,1,2,3,4  到达4之后重新归零
    
    				chanNums[index]<-1 //放入下一个
    			}
    		}(i)
    	}
    
    	//初始化时候先把第一个打印goroutine开启
    	chanNums[0]<-1
    
    	//退出标识存在才会退出
    	select {
    	case <-exitChan:
    		fmt.Println("main终止")
    	}
    }
    
    
  • 相关阅读:
    多个列表根据交集进行合并
    python 在cv2 基础上pillow写文字
    python 欧拉角,旋转矩阵,四元数之间转换
    python 实现循环链表
    模板,用于处理数据
    numba学习一
    centos8下使用mysql安装包安装mysql8.02
    (一)什么是Rabbitmq look
    (4)什么是Ribbon负载均衡 look
    (5)使用Nacos注册中心 look
  • 原文地址:https://www.cnblogs.com/9527s/p/16367084.html
Copyright © 2020-2023  润新知