golang 中, os.exit() runtime.Goexit() return 有什么区别

return结束当前函数,并返回指定值
runtime.Goexit结束当前goroutine,其他的goroutine不受影响,主程序也一样继续运行
os.Exit会结束当前程序,不管你三七二十一

 

 

 

Gosched

暂停当前goroutine,使其他goroutine先行运算。只是暂停,不是挂起,当时间片轮转到该协程时,Gosched()后面的操作将自动恢复

未使用Gosched的代码
package main

import (
	"fmt"
)

func main() {
	go output("goroutine 2")
	
	output("goroutine 1")
}

func output(s string){
	for i:=0;i<3;i++{
		fmt.Println(s)
	}
}
输出
goroutine 1
goroutine 1
goroutine 1

结论:还没等到子协程执行,主协程就已经执行完退出了,子协程将不再执行,所以打印的全部是主协程的数据。当然,实际上这个执行结果也是不确定的,只是大概率出现以上输出,因为主协程和子协程间并没有绝对的顺序关系

使用Gosched的代码
package main

import (
	"fmt"
	"runtime"
)

func main() {
	go output("goroutine 2")

	runtime.Gosched()
	output("goroutine 1")
}

func output(s string){
	for i:=0;i<3;i++{
		fmt.Println(s)
	}
}
输出
goroutine 2
goroutine 2
goroutine 2
goroutine 1
goroutine 1
goroutine 1

结论:在打印goroutine 1之前,主协程调用了runtime.Gosched()方法,暂停了主协程。子协程获得了调度,从而先行打印了goroutine 2。主协程不是一定要等其他协程执行完才会继续执行,而是一定时间。如果这个时间内其他协程没有执行完,那么主协程将继续执行,例如以下例子

使用Gosched的代码,并故意延长子协程的执行时间,看主协程是否一直等待
package main

import (
	"fmt"
	"runtime"
	"time"
)

func main() {
	go func() {
		time.Sleep(5000)
		output("goroutine 2")
	}()

	runtime.Gosched()
	output("goroutine 1")
}

func output(s string) {
	for i := 0; i < 3; i++ {
		fmt.Println(s)
	}
}
输出
goroutine 1
goroutine 1
goroutine 1

Goexit

立即终止当前协程,不会影响其它协程,且终止前会调用此协程声明的defer方法。由于Goexit不是panic,所以recover捕获的error会为nil

当main方法所在主协程调用Goexit时,Goexit不会return,所以主协程将继续等待子协程执行,当所有子协程执行完时,程序报错deadlock

package main

import (
	"fmt"
	"runtime"
	"time"
)

func main() {
	go func(){
		defer func(){
			fmt.Println("defer func executed!")
			fmt.Println("recovered error == ",recover())
		}()

		for i:=0;i<3;i++{
			if i==1{
				runtime.Goexit()
			}

			fmt.Println(i)
		}
	}()

	time.Sleep(2*time.Second)
}
输出
0
defer func executed!
recovered error ==  <nil>

GOMAXPROCS(n int) int

设置可同时执行的逻辑Cpu数量,默认和硬件的线程数一致而不是核心数,可以通过调用GOMAXPROCS(-1)来获取当前逻辑Cpu数

最好在main函数之前设置它,GOMAXPROCS同时也是go的环境变量之一

�6�7 当n<1:非法数字,方法不作修改

�6�7 当n==1:单核心,多协程并发执行,并发只是看起来是同时执行的,实际上是同一时刻只有一个协程在跑,只是由于cpu的任务调度算法,让多个协程在效果上同时执行

�6�7 当n>1:多核心,多协程并行执行,并行一定是并发,不同的核心同时地跑不同的协程

想要了解更多有关并发(Concurrency)和并行(Parallel)的区别,可以看看大神Rob Pike的视频Concurrency Is Not Parallelism,里面有很详细的讲解

作者:胡金生
出处:www.aprilboy.com
版权所有,欢迎保留原文链接进行转载:)

posted on 2021-04-23 15:04  ExplorerMan  阅读(1526)  评论(0编辑  收藏  举报

导航