goroutine协程创建和使用
前言:
协程的创建和使用,Go语言中使用goroutine非常简单,
只需要在调用函数的时候在前面加上go关键字,就可以为一个函数创建一个goroutine。
正文:
函数创建goroutine语法:
go 函数名( 参数列表 )
函数名:要调用的函数名。
参数列表:调用函数需要传入的参数。
goroutine 实例1:
func test() {
fmt.Println("test()", "hello test")
}
main调用:
go test() //增加go关键字,将test函数变为一个协程
fmt.Println("main()", "hello main")
//需要等待协程执行,不等待的话,有可能协程没有执行,程序就退出了
time.Sleep(time.Second)
主程序main,执行完毕,所有开启的协程,也全部退出。所有有时候看到协程,并不会全部执行完毕。
goroutine执行流程
Runtime 包 GOMAXPROCS
Go运行时的调度器使用GOMAXPROCS参数来确定需要使用多少个OS线程来同时执行Go代码。
默认值是机器上的CPU核心数。
使用 runtime.NumCPU() 查询 CPU 数量
使用 runtime.GOMAXPROCS() 函数进行设置当前程序并发时占用的CPU逻辑核心数。
使用 runtime.NumGoroutine() 返回正在执行和排队的任务总数
使用:runtime.Gosched() 让出CPU时间片,重新等待安排任务
使用:runtime.Goexit() 退出当前 goroutine,不执行
多个goroutine交替执行示例:
两个协程交替执行
Go1.5版本之前,默认使用的是单核心执行。
Go1.5版本之后,默认使用全部的CPU逻辑核心
func test1() { for i := 1; i < 10; i++ { fmt.Println("test1()", i) } } func test2() { for i := 1; i < 10; i++ { fmt.Println("test2()", i) } } func main() { runtime.GOMAXPROCS(1) //设置使用的cpu核心数,默认是全部核心 go test1() go test2() //查看CPU数量 fmt.Println(runtime.NumCPU()) //查看正在执行和排队的协程总数 ,输出3 fmt.Println(runtime.NumGoroutine()) fmt.Println("main()", "hello main") time.Sleep(time.Second) //等待协程执行 }
sync.WaitGroup使用
当某个操作或是某个goroutine需要等待一批goroutine执行完毕以后才继续执行,
那么这种多线程(go里面说的线程就是goroutine)等待的问题就可以使用WaitGroup
使用sync.WaitGroup来实现并发任务的同步
地址:https://go-zh.org/pkg/sync/
waitGroup实例1:
需要等待一批协程执行完毕,才可以执行后续操作,就无须使用 time.sleep函数,进行等待
var wg = sync.WaitGroup{} //WaitGroup初始化 func test1() { defer wg.Done() //计数器减一 for i := 1; i < 10; i++ { fmt.Println("test1()", i) } } func test2() { defer wg.Done() //计数器减一 for i := 1; i < 10; i++ { fmt.Println("test2()", i) } } func main() { wg.Add(2) //计数器设置2,表示创建2个协程等待 go test1() go test2() wg.Wait() //需要等待2个goroutine执行完毕以后才继续执行后续 fmt.Println("main()", "hello main") }
runtime.Gosched
让当前线程让出 cpu 以让其它线程运行,它不会挂起当前线程,
因此当前线程未来会继续执行,在其他协程执行完毕后执行
实例1:让出线程,让其他线程运行
var wg = sync.WaitGroup{} func test(n int) { defer wg.Done() if n == 5 { runtime.Gosched() //让当前线程让出 cpu 以让其它协程运行, //其他协程执行完毕才能继续运行当前协程 } fmt.Println("test()", n) } main: runtime.GOMAXPROCS(1) //设置使用的cpu核心数 for i := 0; i < 10; i++ { wg.Add(1) go test(i) } wg.Wait() fmt.Println("main()", "hello main")
输出结果:test() 5 总是在最后执行
完结
但行好事,莫问前程!
本文来自博客园,作者:yangphp,转载请注明原文链接:https://www.cnblogs.com/ypeih/p/17297627.html