浅析Golang中的协程(goroutine)
作者:周小末天天开心 发布时间:2024-04-29 13:05:08
进程
进程就是程序在操作系统中的一次执行过程,是系统进行资源分配和调度的基本单位,进程是一个动态概念,是程序在执行过程中分配和管理资源的基本单位,每一个进程都有一个自己的地址空间。一个进程至少有5种基本状态:初始状态,执行状态,等待状态,就绪状态,终止状态。通俗的讲,进程就是一个正在执行的程序。
线程
线程是进程的一个执行实例,是程序执行的最小单元,它是比进程更小的能独立运行的基本单位。一个进程可以创建多个线程,同一个进程中的多个线程可以并发执行,一个程序要运行的话至少有一个进程。
并发
并发是指在同一时间段内处理多个任务,通过多个任务之间的切换,使得在表面上看来是同时进行的。在 Go 语言中,可以使用 goroutine 和 channel 实现并发编程。
特点:
多个任务作用在一个CPU上面
同一时间点只能有一个任务执行
同一时间段内执行多个任务
并行
并行是指同时处理多个任务,即多个任务同时在不同的处理器上进行执行。并行可以显著提高程序的性能,特别是在多核 CPU 中,能够利用多个 CPU 核心进行计算。在 Go 语言中,可以使用 goroutine 和 runtime 包的 GOMAXPROCS 函数实现并行编程。
特点:
多个任务作用在多个CPU上面
同一时刻执行多个任务
通俗的讲,多线程程序在单核CPU上面运行就是并发,多线程程序在多核CUP上运行就是并行,如果线程数大于CPU核数,则多线程程序在多个CPU上面运行既有并行也有并发。
协程(goroutine)
在 Go 语言中,协程(goroutine)是轻量级的线程,它是 Go 语言中实现并发编程的基础。与传统的线程相比,协程的创建和切换都非常轻量级,可以在单个线程内创建成千上万个协程,且切换开销非常小,因此可以实现高效的并发编程。
Go 语言中的协程是由 Go 运行时调度器(scheduler)进行管理和调度的。当程序启动时,Go 运行时会默认启动一个主协程,主协程会创建其他的子协程,这些协程会被分配到不同的系统线程上进行执行。当某个协程发生阻塞时,Go 运行时会将该协程挂起并让出 CPU,转而执行其他协程,以充分利用系统资源。
在 Go 语言中,创建协程非常简单,只需要在函数调用前加上 go 关键字即可。
例如:
func main() {
go func() {
fmt.Println("Hello, world!")
}()
}
使用sync.WaitGroup等待协程执行完毕
func test1() {
for i := 0; i < 10; i++ {
//每100毫秒输出一次
fmt.Println("test1() 你好Golang-", i)
time.Sleep(time.Millisecond * 100)
}
wg.Done() //协程计数器加-1
}
func main() {
//注意:
//1.主线程执行完毕后即使协程没有执行完毕程序也会退出
//2.协程可以在主线程没有执行完毕前提前退出,协程是否执行完毕不会影响主线程的执行
//为了保证我们的程序可以顺利执行,我们想让协程执行完毕后再执行主进程退出,
//这个时候我们可以使用sync.WaitGroup等待协程执行完毕
wg.Add(1) //协程计数器加1
go test1() //表示开启一个协程
for i := 0; i < 10; i++ {
//每50毫秒输出一次
fmt.Println("mian() 你好Golang-", i)
time.Sleep(time.Millisecond * 50)
}
wg.Wait() //等待协程执行完毕
fmt.Println("主线程退出。。。")
}
多协程和多线程
Golang中每个goroutine(协程)默认占用内存比Java、C的线程少。OS线程(操作系统线程)一般都有固定的栈内存(通常为2MB左右),一个goroutine(协程)占用内存非常少,只有2KB左右,多协程切换调度开销方面远比线程要少。这也是为什么越来越多的大公司使用Golang的原因之一。
func test1() {
for i := 0; i < 10; i++ {
//每100毫秒输出一次
fmt.Println("test1() 你好Golang-", i)
time.Sleep(time.Millisecond * 100)
}
wg.Done() //协程计数器加-1
}
func test2() {
for i := 0; i < 10; i++ {
//每100毫秒输出一次
fmt.Println("test2() 你好Golang-", i)
time.Sleep(time.Millisecond * 100)
}
wg.Done() //协程计数器加-1
}
func main() {
wg.Add(1) //协程计数器加1
go test1() //表示开启一个协程
wg.Add(1) //协程计数器加1
go test2() //表示开启一个协程
wg.Wait()
fmt.Println("主程序退出。。。")
}
来源:https://blog.csdn.net/weixin_71646897/article/details/130787446


猜你喜欢
- 废话不多说了,直接给大家贴代码了,具体代码如下所述:<!DOCTYPE html><html><head>
- 以下内容给大家c#连接数据库的方法的相关介绍,本文非常具有参考借鉴价值,具体详情如下所示。ASP.NET连接数据库的技术叫ADO.NET,它
- 我们能否使用一些自动化工具代替人来完成数据分析的过程呢,现有一些成熟的 AutoEDA 工具可以一定程度上完成上述过程。本文中,我将盘点常见
- 接下来就是数据结构的第一部分,栈。栈是一种遵从后进先出原则(LIFO,全称为Last In First Out)的有序集合。栈顶永远是最新的
- 一、采用?a=1&b=2访问修改views.py:views.pyfrom django.shortcuts import rend
- 存储过程与编码MySQL 存储过程中, 表和数据的编码与数据库和存储过程默认的编码不同则可能出现 sql 不会使用索引的情况, 因为 MyS
- 目录Pyppeteer 是什么Pyppeteer能做什么截图导出PDF公众号链接导出PDF示例Pyppeteer 是什么介绍 Pyppete
- pygal的安装大家可以参阅:pip和pygal的安装实例教程线图:import pygalline_chart = pygal.Line(
- 工欲善其事,必先利其器,开发工具这个东西觉得折腾下还是有好处的。但常常感觉专门抽出时间搞这个浪费时间,更常见的现象是已经明显感觉到当前的开发
- 安装pyinstallpip install pyinstaller注意事项除非必要,否则尽量不要直接import module,用from
- Typora是什么?Typora是一款支持实时预览的Markdown文本编辑器。支持即时渲染技术,这也是与其他Markdown编辑器最显著的
- 多表连接查询表与表之间的连接分为内连接和外连接内连接:仅选出两张表互相匹配的记录外连接:既包括两张表匹配的记录,也包括不匹配的记录,同时外连
- Pivot 及 Pivot_table函数用法Pivot和Pivot_table函数都是对数据做透视表而使用的。其中的区别在于Pivot_t
- 源由刚开始是帮朋友做一个按键精灵操作旺信的脚本,写完后各种不稳定;后来看到python可以操作win32相关的api,恰好这一段时间正在学习
- CSRFCSRF全拼为Cross Site Request Forgery,译为跨站请求伪造。CSRF指攻击者盗用了你的身份,以你的名义发送
- 一、在javascript中嵌入php代码javascript若是通过js文件包含进来的,那么js文件中也可以直接写php代码,
- 本文实例讲述了Python with关键字,上下文管理器,@contextmanager文件操作。分享给大家供大家参考,具体如下:demo.
- 一、利用直方图的方式进行批量的图片缺陷检测(方法简单)二、步骤(完整代码见最后)2.1灰度转换(将原图和要检测对比的图分开灰度化)灰度化的作
- 数据表:列转行:利用max(case when then)max---聚合函数 取最大值(case course when '语文&
- 这些天,我需要全文搜索。这个区块中最酷的孩子们是Elastic Search和Sorl:他们快速,灵活,资源消耗沉重并且需要Java,这几乎