zoukankan      html  css  js  c++  java
  • 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)
    	}
    }
    
  • 相关阅读:
    sql 删除默认索引,对象 依赖于 列,由于一个或多个对象访问此列
    sql 重复数据查询
    Sql 查询结果 根据某个字段值 变更另外一个字段值 case when
    使用ABP框架踩过的坑系列3
    使用ABP框架踩过的坑系列5
    使用ABP框架踩过的坑系列4
    使用ABP框架踩过的坑系列2
    使用ABP框架踩过的坑系列1
    java rest框架jersey数组单记录问题解决
    测试工程师面试常见逻辑题
  • 原文地址:https://www.cnblogs.com/kikochz/p/13504184.html
Copyright © 2011-2022 走看看