Go协程并发之百万级并发「让我们一起Golang」

简介: Go协程并发之百万级并发「让我们一起Golang」

Go协程并发之百万级并发「让我们一起Golang」

前面我们介绍了关于Golang的协程并发的一些理论知识,接下来我们上代码,通过代码带大家了解一下Go的协程并发,体验Go的百万级并发。

我们先来了解一下进程、线程、协程的区别吧!

进程有自己独立的堆和栈,而线程虽然拥有独立的栈,但是它的堆是共享的。而我们这里要讲的协程和线程是一样的,也是只共享堆,而不共享栈。但是协程不像进程和线程那样由操作系统调度,而是由程序员来调度,这样就可以节省资源,提高性能。

下面来看看主协程和一条协程在并发执行时的表现吧!

func main()  {
    go func() {
        for{
            fmt.Println("i am coroutine")
            time.Sleep(time.Second)
        }
    }()

    for{
        fmt.Println("我是主协程")
        time.Sleep(time.Second)
    }
}

他们运行结果是:

我是主协程
i am coroutine
i am coroutine
我是主协程
我是主协程
i am coroutine
i am coroutine
我是主协程
i am coroutine
我是主协程

我们可以看到,他们并不是顺序执行的,而是并发执行的,这就是协程并发。

func main() {
    //但是开启100条小协程是主协程干的
    //迅速开启100条小协程
    for i:=0;i<10;i++{
        go doSomething("面包人"+strconv.Itoa(i))
    }

    for{
        fmt.Println("我是主协程")
        time.Sleep(time.Second)
    }
}

func doSomething(grname string)  {
    for{
        fmt.Println("来了一车",grname)
        time.Sleep(time.Second)
    }
}
来了一车 面包人0
来了一车 面包人7
来了一车 面包人8
我是主协程
来了一车 面包人2
来了一车 面包人6
来了一车 面包人3
来了一车 面包人1
来了一车 面包人5
来了一车 面包人9
来了一车 面包人4
来了一车 面包人0
来了一车 面包人8
来了一车 面包人1
来了一车 面包人2
来了一车 面包人4
来了一车 面包人7
来了一车 面包人3
来了一车 面包人9
来了一车 面包人5
我是主协程
来了一车 面包人6
来了一车 面包人1
来了一车 面包人4

这里体验的是11条协程并发。是主协程唤起了十条协程,然后才有一车车面包人来打你。因此主协程是那个打电话喊面包人打你的人。也就是说主协程开启了10条协程。但是这十一条协程是并发的,他们不是顺序执行的。虽然是并发执行的,但是在微观上每次还是只能执行一条协程,但是他们的执行顺序和创建顺序是不一致的。

然后将

for i:=0;i<10;i++{
        go doSomething("面包人"+strconv.Itoa(i))
    }

改为

for i:=0;i<1000000;i++{
        go doSomething("面包人"+strconv.Itoa(i))
    }

这就是百万级并发了!

一个主协程可以喊100万车面包人打你。

经过测试,程序持续1分钟都没有崩溃。事实证明,执行协程只需要消耗极少的内存和CPU资源,所以我们可以创建一百万条协程。16G内存的电脑,用JAVA,C来做并发,差不多也就千级并发,而用GO语言,通过管道可以让并发能力得到很大提升,我们这里实现了百万级并发。

goroutine是协作式调度的,而Java等的使用的线程是抢占式调度的。

目录
相关文章
|
5月前
|
Java 编译器 Go
【Golang】(1)Go的运行流程步骤与包的概念
初次上手Go语言!先来了解它的运行流程吧! 在Go中对包的概念又有怎样不同的见解呢?
305 4
|
5月前
|
Java 编译器 Go
【Golang】(5)Go基础的进阶知识!带你认识迭代器与类型以及声明并使用接口与泛型!
好烦好烦好烦!你是否还在为弄不懂Go中的泛型和接口而烦恼?是否还在苦恼思考迭代器的运行方式和意义?本篇文章将带你了解Go的接口与泛型,还有迭代器的使用,附送类型断言的解释
274 3
|
5月前
|
存储 安全 Java
【Golang】(4)Go里面的指针如何?函数与方法怎么不一样?带你了解Go不同于其他高级语言的语法
结构体可以存储一组不同类型的数据,是一种符合类型。Go抛弃了类与继承,同时也抛弃了构造方法,刻意弱化了面向对象的功能,Go并非是一个传统OOP的语言,但是Go依旧有着OOP的影子,通过结构体和方法也可以模拟出一个类。
309 2
|
7月前
|
Go 调度 Python
Golang协程和Python协程用法上的那些“不一样”
本文对比了 Python 和 Go 语言中协程的区别,重点分析了调度机制和执行方式的不同。Go 的协程(goroutine)由运行时自动调度,启动后立即执行;而 Python 协程需通过 await 显式调度,依赖事件循环。文中通过代码示例展示了两种协程的实际运行效果。
310 7
|
8月前
|
人工智能 测试技术 持续交付
Golang深入浅出之-Go语言中的持续集成与持续部署(CI/CD)
持续集成与持续部署(CI/CD)是现代软件开发的关键实践,尤其适用于Go语言项目。本文探讨了Go项目中常见的CI/CD问题,如测试覆盖不足、版本不一致和构建时间过长,并提供解决方案及GitHub Actions示例代码,帮助开发者优化流程,提升交付效率和质量。
262 5
|
7月前
|
数据采集 Go API
Go语言实战案例:多协程并发下载网页内容
本文是《Go语言100个实战案例 · 网络与并发篇》第6篇,讲解如何使用 Goroutine 和 Channel 实现多协程并发抓取网页内容,提升网络请求效率。通过实战掌握高并发编程技巧,构建爬虫、内容聚合器等工具,涵盖 WaitGroup、超时控制、错误处理等核心知识点。
|
12月前
|
Go 开发者
go-carbon v2.6.0 重大版本更新,轻量级、语义化、对开发者友好的 golang 时间处理库
carbon 是一个轻量级、语义化、对开发者友好的 Golang 时间处理库,提供了对时间穿越、时间差值、时间极值、时间判断、星座、星座、农历、儒略日 / 简化儒略日、波斯历 / 伊朗历的支持
258 3
|
存储 安全 测试技术
GoLang协程Goroutiney原理与GMP模型详解
本文详细介绍了Go语言中的Goroutine及其背后的GMP模型。Goroutine是Go语言中的一种轻量级线程,由Go运行时管理,支持高效的并发编程。文章讲解了Goroutine的创建、调度、上下文切换和栈管理等核心机制,并通过示例代码展示了如何使用Goroutine。GMP模型(Goroutine、Processor、Machine)是Go运行时调度Goroutine的基础,通过合理的调度策略,实现了高并发和高性能的程序执行。
933 29
|
JSON Go 开发者
go-carbon v2.5.0 发布,轻量级、语义化、对开发者友好的 golang 时间处理库
carbon 是一个轻量级、语义化、对开发者友好的 Golang 时间处理库,提供了对时间穿越、时间差值、时间极值、时间判断、星座、星座、农历、儒略日 / 简化儒略日、波斯历 / 伊朗历的支持。
316 4
|
存储 Cloud Native Shell
go库介绍:Golang中的Viper库
Viper 是 Golang 中的一个强大配置管理库,支持环境变量、命令行参数、远程配置等多种配置来源。本文详细介绍了 Viper 的核心特点、应用场景及使用方法,并通过示例展示了其强大功能。无论是简单的 CLI 工具还是复杂的分布式系统,Viper 都能提供优雅的配置管理方案。
451 6