在Go语言(Golang)中,实现并发编程主要依赖于其轻量级的线程——goroutines和通信机制channels。以下是一些基本的步骤和示例,帮助你在Linux环境中使用Go实现并发编程:
Goroutines是Go语言中实现并发的基本单位。你可以通过在函数调用前加上go
关键字来启动一个新的goroutine。
package main
import (
"fmt"
"time"
)
func printNumbers() {
for i := 1; i <= 5; i++ {
fmt.Printf("Number: %d\n", i)
time.Sleep(1 * time.Second)
}
}
func main() {
go printNumbers() // 启动一个新的goroutine
// 主goroutine继续执行
fmt.Println("Main function is running")
time.Sleep(6 * time.Second) // 等待足够的时间以便观察goroutine的输出
}
Channels是Go语言中用于goroutines之间通信和同步的机制。你可以使用channel来传递数据或者作为信号通知。
package main
import (
"fmt"
"time"
)
func produce(c chan<- int) {
for i := 0; i < 5; i++ {
c <- i // 发送数据到channel
time.Sleep(time.Second)
}
close(c) // 关闭channel
}
func consume(c <-chan int) {
for num := range c { // 从channel接收数据直到它被关闭
fmt.Println(num)
}
}
func main() {
c := make(chan int) // 创建一个int类型的channel
go produce(c) // 启动生产者goroutine
consume(c) // 启动消费者goroutine
time.Sleep(6 * time.Second) // 等待足够的时间以便观察输出
}
有时候你需要确保所有的goroutines都完成后再退出主程序。这时可以使用sync.WaitGroup
来实现同步。
package main
import (
"fmt"
"sync"
"time"
)
func worker(id int, wg *sync.WaitGroup) {
defer wg.Done() // 在函数结束时调用Done()来通知WaitGroup一个goroutine已经完成
fmt.Printf("Worker %d starting\n", id)
time.Sleep(time.Second)
fmt.Printf("Worker %d done\n", id)
}
func main() {
var wg sync.WaitGroup
for i := 1; i <= 5; i++ {
wg.Add(1) // 增加WaitGroup的计数器
go worker(i, &wg) // 启动goroutine
}
wg.Wait() // 等待所有goroutines完成
fmt.Println("All workers done")
}
context
包提供了在多个goroutines之间传递截止时间、取消信号和其他请求范围值的方法。
package main
import (
"context"
"fmt"
"time"
)
func doSomething(ctx context.Context) {
for {
select {
case <-ctx.Done(): // 监听ctx.Done()通道
fmt.Println("Context cancelled or timed out")
return
default:
fmt.Println("Working...")
time.Sleep(500 * time.Millisecond)
}
}
}
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel() // 确保在main函数结束时调用cancel()
go doSomething(ctx)
time.Sleep(3 * time.Second) // 等待足够的时间以便观察doSomething的行为
}
以上就是在Linux中使用Go语言实现并发编程的一些基本方法。通过合理地使用goroutines、channels和sync包中的工具,你可以构建出高效且易于维护的并发程序。