8小时golang速成(五)Golang高阶 创建 goroutine

 

 

Go并发

Go 在语言级别支持协程,叫goroutine。Go 语言标准库提供的所有系统调用操作(包括所有同步IO操作)

都会出让CPU给其他goroutine。这让轻量级线程的切换管理不依赖于系统的线程和进程,也不需要依赖于CPU的核心数量。

 

有人把Go比作21世纪的C语言。第一是因为Go语言设计简单,第二,21世纪最重要的就是并行程序设计,而Go从语言层面就支持并发。同时,并发程序的内存管理有时候是非常复杂的,而Go语言提供了自动垃圾回收机制。

 

Go语言为并发编程而内置的上层API基于顺序通信进程模型CSP(communicating sequential processes)。这就意味着显式锁都是可以避免的,因为Go通过相对安全的通道发送和接受数据以实现同步,这大大地简化了并发程序的编写。

 

Go语言中的并发程序主要使用两种手段来实现。goroutine和channel。

 

什么是Goroutine

goroutine是Go语言并行设计的核心,有人称之为go程。 Goroutine从量级上看很像协程,它比线程更小,十几个goroutine可能体现在底层就是五六个线程,Go语言内部帮你实现了这些goroutine之间的内存共享。执行goroutine只需极少的栈内存(大概是4~5KB),当然会根据相应的数据伸缩。也正因为如此,可同时运行成千上万个并发任务。goroutine比thread更易用、更高效、更轻便。

一般情况下,一个普通计算机跑几十个线程就有点负载过大了,但是同样的机器却可以轻松地让成百上千个goroutine进行资源竞争。

 

创建Goroutine

只需在函数调用语句前添加 go 关键字,就可创建并发执行单元。开发人员无需了解任何执行细节,调度器会自动将其安排到合适的系统线程上执行。

 

在并发编程中,我们通常想将一个过程切分成几块,然后让每个goroutine各自负责一块工作,

 

当一个程序启动时,主函数在一个单独的goroutine中运行,我们叫它main goroutine

新的goroutine会用go语句来创建。而go语言的并发设计,让我们很轻松就可以达成这一目的。

 

Attention!!!!!!

go 后面加 一个函数 或者 一个匿名函数  就可以创建一个 goroutine 

子协程 return 的值 不能当做 返回值 返回给 主协程,所以交流引入 chanel 概念

runtime.Goexit()  退出当前的goroutine

 

 例子1  

复制代码
package main
import (
    "fmt"
    "time"
)

//子goroutine
func newTask() {
    i := 0
    for {
        i++
        fmt.Printf("new Goroutine : i = %d\n", i)
        time.Sleep(1 * time.Second)
    }
}

//主goroutine
func main() {
    //创建一个go程序 去执行newTask() 流程
    go newTask()

    fmt.Println("main goroutine exit")

    /*
        i := 0
        for {
            i++
            fmt.Printf("main goroutine: i = %d\n", i)
            time.Sleep(1 * time.Second)
        }
    */
}
复制代码
结果

Goroutine特性

主goroutine退出后,其它的工作goroutine也会自动退出:

复制代码
package main
import (
"fmt"
"time"
)
 
func newTask() {
    i := 0
    for {
        i++
        fmt.Printf("new goroutine: i = %d\n", i)
        time.Sleep(1 * time.Second) //延时1s
    }
}
 
func main() {
    //创建一个 goroutine,启动另外一个任务
    go newTask()
 
    fmt.Println("main goroutine exit")
}
复制代码

结果:

 

 

Goexit函数

调用 runtime.Goexit() 将立即终止当前 goroutine 执⾏,调度器确保所有已注册 defer 延迟调用被执行。

示例代码:

复制代码
package main
 
import (
"fmt"
"runtime"
)
 
func main() {
    go func() {
        defer fmt.Println("A.defer")
 
        func() {
            defer fmt.Println("B.defer")
            runtime.Goexit() // 终止当前 goroutine, import "runtime"
            fmt.Println("B") // 不会执行
        }()
 
        fmt.Println("A") // 不会执行
    }()       //不要忘记()
 
    //死循环,目的不让主goroutine结束
    for {
    }
}
复制代码

结果

 

 











posted @   陈晓猛  阅读(26)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示