【Go进阶】协程的创建以及通信

news/2024/10/15 5:35:03/

Goroutine

在 Go 语言中,协程(goroutine)是一种轻量级的执行线程。以下是关于协程的详细介绍:

一、定义与特点

  • 轻量级:协程是一种非常轻量级的执行单元,相比传统的操作系统线程,协程的创建和切换开销非常小。创建一个协程只需要几 KB 的栈空间,而操作系统线程通常需要几 MB 的栈空间。这使得在 Go 语言中可以轻松创建大量的协程,而不会给系统带来沉重的负担。
  • 并发性:协程允许在一个程序中同时执行多个任务,实现并发执行。多个协程可以在同一个进程中并发地执行,共享进程的内存空间和资源。这使得并发编程更加高效和灵活。
  • 非阻塞式执行:协程可以在等待某个操作完成时(如网络 I/O、文件读取等)暂停执行,而不会阻塞整个程序的执行。当操作完成时,协程可以被恢复执行,继续处理后续的任务。这种非阻塞式的执行方式可以提高程序的响应性和性能。

二、创建与使用

使用关键字go创建协程:在 Go 语言中,可以使用go关键字来创建一个协程。例如:

package mainimport ("fmt""time"
)func printNumbers() {for i := 1; i <= 5; i++ {fmt.Println(i)time.Sleep(time.Millisecond * 500)}
}func main() {// 创建一个协程执行 printNumbers 函数go printNumbers()// 主协程继续执行其他任务for i := 6; i <= 10; i++ {fmt.Println(i)time.Sleep(time.Millisecond * 500)}
}

执行过程

  • 程序启动后,主协程和新创建的协程同时开始执行。
  • 主协程和协程交替执行,因为它们都在睡眠一定时间后继续执行下一次循环。具体的执行顺序取决于 Go 语言的调度器,可能会有所不同。
  • 最终,程序会打印出 1 到 10 的数字,但顺序可能不是严格按照顺序打印,因为两个协程是并发执行的。

在这个例子中,printNumbers函数在一个协程中执行,同时主协程也在执行其他任务。两个协程并发地执行,交替打印数字。

channel

协程之间的通信:协程之间可以通过通道(channel)进行通信。通道是一种类型安全的通信机制,可以在协程之间传递数据。

一、定义与特点

  • 通信机制channel是一种类型安全的通信管道,允许一个协程向另一个协程发送和接收数据。它提供了一种同步和协调不同协程执行的方式,确保数据在协程之间安全地传递。
  • 类型安全channel是有类型的,在创建channel时需要指定所传输数据的类型。例如,可以创建一个传输整数类型的channelch := make(chan int),或者一个传输字符串类型的channelch := make(chan string)
  • 阻塞特性:当一个协程向一个已满的channel发送数据时,该协程会被阻塞,直到另一个协程从channel中接收数据,腾出空间。同样,当一个协程从一个空的channel接收数据时,该协程也会被阻塞,直到另一个协程向channel中发送数据。

二、创建与使用

  • 创建通道:使用make函数来创建一个channel。例如:ch := make(chan int)创建了一个可以传输整数类型数据的通道。
  • 发送数据:使用<-操作符向channel发送数据。例如:ch <- valuevalue发送到channel ch中。
  • 接收数据:同样使用<-操作符从channel接收数据。例如:value := <-chchannel ch中接收一个数据,并赋值给value
  • 关闭通道:使用close函数来关闭一个channel。例如:close(ch)关闭通道ch。关闭通道后,不能再向通道中发送数据,但仍然可以从通道中接收剩余的数据,直到通道为空。
package mainimport ("fmt"
)func sendData(ch chan int) {for i := 1; i <= 5; i++ {ch <- i}close(ch)
}func main() {ch := make(chan int)// 创建一个协程执行 sendData 函数go sendData(ch)// 主协程从通道中接收数据for num := range ch {fmt.Println(num)}
}

在这个例子中,一个协程向通道中发送数据,另一个协程从通道中接收数据。通过通道实现了协程之间的数据传递。

三、应用场景

  • 网络编程:在网络编程中,协程可以用于处理多个并发的网络连接。例如,一个 Web 服务器可以使用协程来处理多个并发的 HTTP 请求,每个请求都在一个独立的协程中处理,提高服务器的并发处理能力。
  • 异步 I/O 操作:当进行异步的文件读取、数据库查询等 I/O 操作时,协程可以在等待操作完成时暂停执行,不会阻塞其他任务的执行。一旦操作完成,协程可以被恢复执行,继续处理后续的任务。
  • 并行计算:对于可以并行执行的任务,可以使用协程来实现并行计算,提高程序的性能。例如,对一个大型数组进行并行计算,可以将数组分成多个部分,每个部分在一个独立的协程中进行计算,最后将结果合并。

总之,协程是 Go 语言中一种非常强大的并发编程工具,它提供了轻量级、高效的并发执行方式,使得开发者可以更加轻松地编写并发程序。


http://www.ppmy.cn/news/1539288.html

相关文章

实战篇:(三)项目实战Vue 3 + WebGL 创建一个简单的 3D 渲染应用

Vue 3 WebGL 创建一个简单的 3D 渲染应用 我们将使用 Vue 3 和 WebGL 创建一个简单的 3D 渲染应用。项目将展示如何在 Vue 组件中集成 WebGL&#xff0c;并渲染一个旋转的立方体。 1. 项目准备 首先&#xff0c;确保你已经安装了 Node.js 和 Vue CLI。如果还没有安装&#x…

flutter鸿蒙版本数据处理常用总集

写在前面 本地访问json 1. 确保文件路径正确 示例目录 确保文件 one.json 实际上位于项目的 assets/json/ 目录中。项目结构应该类似于&#xff1a; your_flutter_project/ │ ├── assets/ │ └── json/ │ └── one.json │ ├── lib/ │ └── mai…

vue3 element table 插槽外的数据更新,插槽内的数据未更新。

在使用element table组件时候&#xff0c;有时候需要对table内部的header插槽进行单独的列的数据操作&#xff0c;比如在列头增加一个筛选功能&#xff0c;对指定范围的值进行一个筛选&#xff0c;需要对input的值进行v-model的绑定&#xff0c;对绑定的值进行清空时候&#xf…

了解Android中的Activity生命周期

Android中的Activity生命周期详解 Android中的Activity是应用程序的基本组成单元&#xff0c;它为用户提供了一个可以交互的界面。Activity的生命周期是指从Activity被创建到销毁的整个过程&#xff0c;其中包含了多个状态转换和相应的系统回调方法。理解Activity的生命周期对…

系统架构设计师教程 第16章 16.1 嵌入式系统概述 笔记

16.1 嵌入式系统概述 嵌入式系统 (Embedded System) 是为了特定应用专门构建的计算机系统&#xff0c;其架构是随着嵌入式系统的逐步应用而发展形成。 16.1.1 嵌入式系统发展历程 五个阶段&#xff1a; 一&#xff1a;单片微型计算机 (SCM) 阶段&#xff0c;即单片机时代。…

使用 iperf3 工具测试TCP/UDP吞吐量

测试目标 - 测试网络的 TCP 和 UDP 吞吐量性能&#xff0c;包括不同并发连接数和目标带宽条件下的表现。 测试环境 - **测试工具**: iperf3 - **固定 IP 地址**: - 服务器 IP: 192.168.1.10 - 客户端 IP: 192.168.1.20 - **端口号**: 5201 测试准备 1. **安装 iperf3**&a…

【图论】Dijkstra

Dijkstra 前置知识 堆图论基础Bellman-Ford 思路 Dijkstra 算法是一种求正权图单源最短路的算法。 注意到BF最大的缺陷在于其对于一个点的松弛方式太暴力了。 注意到有正权这个条件。 那么我们发现&#xff0c;只要选取当前距离最小的点&#xff0c;该点不可能被松弛。 于是…

Spring-事务的其他属性

说到事务&#xff0c;就要说事务的隔离级别&#xff1a; 事务还有回滚&#xff0c;这里也有回滚的控制属性&#xff1a; rollbackFor可以指定对遇到什么异常回滚事务&#xff1a;默认是所有的运行时异常都要回滚&#xff0c;这个属性&#xff0c;知道就行&#xff0c;一般就取默…