
目录
1.并发简介
并发是同时处理多个任务的能力。在 go 中,并发性是一等公民,内置于该语言的核心设计中。 go 的并发方法基于通信顺序进程(csp),该模型强调进程之间的通信而不是共享内存。
2.并发与并行:
go 例程支持并发,这是独立执行进程的组合。
如果系统有多个 cpu 核心并且 go 运行时安排 go 例程并行运行,则可能会发生并行(同时执行)。
3。 go 例程:
并发的构建块是 go 例程,是由 go 运行时管理的轻量级线程。它是与其他函数或方法同时运行的函数或方法。 go 例程是 go 并发模型的基础。
主要特征:
创建 go 例程:
要启动 go 例程,只需使用 go 关键字,后跟函数调用:
go functionname()
或者使用匿名函数:
go func() {
// function body
}()
go-routine 调度:
通讯与同步:
示例及说明:
package main
import (
"fmt"
"time"
)
func printnumbers() {
for i := 1; i <= 5; i++ {
time.sleep(100 * time.millisecond)
fmt.printf("%d ", i)
}
}
func printletters() {
for i := 'a'; i <= 'e'; i++ {
time.sleep(150 * time.millisecond)
fmt.printf("%c ", i)
}
}
func main() {
go printnumbers()
go printletters()
time.sleep(2 * time.second)
fmt.println("\nmain function finished")
}
说明:
goroutine 生命周期:
最佳实践:
带有 go 例程解释的简单示例
package main
import (
"fmt"
"time"
)
// printnumbers is a function that prints numbers from 1 to 5
// it will be run as a goroutine
func printnumbers() {
for i := 1; i <= 5; i++ {
time.sleep(500 * time.millisecond) // sleep for 500ms to simulate work
fmt.printf("%d ", i)
}
}
// printletters is a function that prints letters from 'a' to 'e'
// it will also be run as a goroutine
func printletters() {
for i := 'a'; i <= 'e'; i++ {
time.sleep(300 * time.millisecond) // sleep for 300ms to simulate work
fmt.printf("%c ", i)
}
}
func main() {
// start printnumbers as a goroutine
// the 'go' keyword before the function call creates a new goroutine
go printnumbers()
// start printletters as another goroutine
go printletters()
// sleep for 3 seconds to allow goroutines to finish
// this is a simple way to wait, but not ideal for production code
time.sleep(3 * time.second)
// print a newline for better formatting
fmt.println("\nmain function finished")
}
4.频道:
通道是 go 中的一项核心功能,它允许 go 例程相互通信并同步执行。它们为一个 go 例程提供了一种将数据发送到另一个 go 例程的方法。
频道的目的
go 中的通道有两个主要用途:
a) 通信:它们允许 goroutine 相互发送和接收值。
b) 同步:它们可用于跨 goroutine 同步执行。
创建:使用 make 函数创建通道:
ch := make(chan int) // unbuffered channel of integers
发送:使用 <- 运算符将值发送到通道:
ch <- 42 // send the value 42 to the channel
接收:使用 <- 运算符从通道接收值:
value := <-ch // receive a value from the channel
频道类型
a) 无缓冲通道:
ch := make(chan int)
go func() {
ch <- 42 // this will block until the value is received
}()
value := <-ch // this will receive the value
b) 缓冲通道:
ch := make(chan int, 2) ch <- 1 // doesn't block ch <- 2 // doesn't block ch <- 3 // this will block until a value is received
频道方向
通道可以是定向的或双向的:
示例:
func send(ch chan<- int) {
ch <- 42
}
func receive(ch <-chan int) {
value := <-ch
fmt.println(value)
}
关闭频道
可以关闭通道以表示不再发送任何值:
close(ch)
从封闭通道接收:
如果通道为空,则返回通道类型的零值。
您可以使用二值接收来检查通道是否关闭:
value, ok := <-ch
if !ok {
fmt.println("channel is closed")
}
跨频道
您可以使用 for range 循环从通道接收值,直到通道关闭:
for value := range ch {
fmt.Println(value)
}
嘿,感谢您坚持到最后!我感谢您成为有价值的读者和学习者。请在此处以及我的 linkedin 和 github 上关注我 .
以上就是Go 中的并发:从基础知识到高级概念的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号