• Golang 协程


    Golang 协程

    协程的特点

    • 独立的栈空间
    • 共享程序堆空间
    • 调度由用户控制
    • 协程是轻量级的线程
    • 如果函数有返回值, 使用协程时, 返回值将被吞掉

    案例

    编写一个程序完成如下功能:

    1. 在主线程中,开启一个goroutine, 该协程每隔1秒输出“hello world”
    2. 在主线程中也每隔一秒输出“hello golang”, 输出10次
    3. 要求主线程和goroutine同时执行
    func test(){
    	for i := 0; i < 10; i++ {
    		fmt.Println("hello world",i)
    		time.Sleep(time.Second)
    	}
    }
    func main() {
    	go test()
    	for i := 0; i < 10; i++ {
    		fmt.Println("hello golang", i)
    		time.Sleep(time.Second)
    	}
    }
    

    主线程和协程的执行流程图

    与Java中的线程不同,Java如果没有设置守护线程,main线程需要在其他线程结束后才会退出

    获取cpu核数

    func main() {
            //cp逻辑核数等同于Java中的Runtime.getRuntime().availableProcessors();
    	cpu := runtime.NumCPU()
    	fmt.Println(cpu)// 8
            //设置运行的逻辑cpu个数, 并返回先前的配置
            cpu = runtime.GOMAXPROCS(4)
            fmt.Println(cpu)// 8
    }
    

    Goshced

    func main() {
       for i := 0; i < 5; i++ {
          go func(i int) {
             if i == 3 {
                //相当于Java的yield
                runtime.Gosched()
             }
             for j := 0; j < 10; j++ {
                fmt.Println("task", i,"====>", j)
             }
          }(i)
       }
       for true {
    
       }
    }
    /*~~~~~~~~~~~~~~~~~~~~~~*/
    func main() {
    	//协程还没有启动主线程就已经跑完for, i大概率为5
    	for i := 0; i < 5; i++ {
    		go func(num int) {
                            //闭包可以访问外部的内容
    			if i == 3 {
    				//相当于Java的yield
    				runtime.Gosched()
    			}
    			for j := 0; j < 10; j++ {
    				fmt.Println("task", i,"====>", j)
    			}
    		}(100)
    	}
    	for true {
    
    	}
    }
    

    Goexit

    func task(){
    	for i := 0; i < 10; i++ {
    		if i == 5 {
    			//主动退出当前运行的协程
    			runtime.Goexit()
    		}
    		fmt.Println(i)
    	}
    }
    func main() {
    	go task()
    	for true {
    
    	}
    }
    

    如果主线程主动退出, 子线程就会自己运行, 直到死锁

    func task(){
    	for i := 0; i < 10; i++ {
    		fmt.Println("task",i)
    	}
    }
    func main() {
    	go task()
    	for i := 0; i < 10; i++ {
    		if i == 3 {
    			runtime.Goexit // 主线程主动退出
    		}
    		fmt.Println("main",i)
    	}
    }
    
  • 相关阅读:
    好的文章聚集地
    java连接mysql数据库8.0以上版本过程中遇到的坑
    Tomcat8.5安装与配置的坑
    用阿里fastJson解析Json字符串
    通过java代码HttpRequestUtil(服务器端)发送HTTP请求并解析
    Vue中美元$符号的意思
    java的jdk和jre区别
    java正则
    java8 四大核心函数式接口Function、Consumer、Supplier、Predicate(转载)
    SpringBoot:静态资源的访问和配置(转载)
  • 原文地址:https://www.cnblogs.com/kikochz/p/13504184.html
Copyright © 2020-2023  润新知