引言
协程(goroutine)是Go语言并发编程的核心,它允许程序并发执行多个任务,同时保持资源消耗低。本篇文章将通过10个实用例子,帮助读者轻松入门协程编程。
一、什么是协程?
协程是轻量级的线程,由Go运行时管理。它可以在单个线程内并发执行多个任务,并且比线程更轻量,创建和切换的开销更小。
二、创建协程
在Go中,使用go
关键字可以创建一个新的协程。以下是一个简单的例子:
package main
import "fmt"
func main() {
go sayHello()
sayHello()
}
func sayHello() {
fmt.Println("Hello, World!")
}
在这个例子中,sayHello
函数在一个新的协程中并发执行。
三、示例1:打印数字序列
package main
import (
"fmt"
"time"
)
func main() {
for i := 0; i < 10; i++ {
go printNumber(i)
}
}
func printNumber(i int) {
time.Sleep(time.Second)
fmt.Println(i)
}
在这个例子中,我们创建了10个协程,每个协程打印一个数字序列。
四、示例2:使用通道进行通信
package main
import (
"fmt"
"time"
)
func main() {
ch := make(chan int)
go func() {
for i := 0; i < 5; i++ {
ch <- i
time.Sleep(time.Second)
}
close(ch)
}()
for num := range ch {
fmt.Println(num)
}
}
在这个例子中,我们使用通道ch
在主协程和另一个协程之间进行通信。
五、示例3:并发读取文件
package main
import (
"bufio"
"fmt"
"os"
"sync"
)
func main() {
file, err := os.Open("example.txt")
if err != nil {
panic(err)
}
defer file.Close()
var wg sync.WaitGroup
reader := bufio.NewReader(file)
for i := 0; i < 10; i++ {
wg.Add(1)
go func() {
defer wg.Done()
line, _, err := reader.ReadLine()
if err != nil {
panic(err)
}
fmt.Println(string(line))
}()
}
wg.Wait()
}
在这个例子中,我们使用协程并发读取文件中的每一行。
六、示例4:使用WaitGroup同步协程
package main
import (
"fmt"
"sync"
"time"
)
func main() {
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
wg.Add(1)
go func(i int) {
defer wg.Done()
time.Sleep(time.Duration(i) * time.Second)
fmt.Println(i)
}(i)
}
wg.Wait()
}
在这个例子中,我们使用WaitGroup
来同步5个协程的执行。
七、示例5:使用select处理多个通道
package main
import (
"fmt"
"time"
)
func main() {
ch1 := make(chan int)
ch2 := make(chan int)
go func() {
for i := 0; i < 5; i++ {
ch1 <- i
time.Sleep(time.Second)
}
close(ch1)
}()
go func() {
for i := 0; i < 5; i++ {
ch2 <- i
time.Sleep(time.Second)
}
close(ch2)
}()
for {
select {
case num := <-ch1:
fmt.Println("From ch1:", num)
case num := <-ch2:
fmt.Println("From ch2:", num)
}
}
}
在这个例子中,我们使用select
语句同时处理两个通道的数据。
八、示例6:使用Mutex保护共享资源
package main
import (
"fmt"
"sync"
"time"
)
func main() {
var wg sync.WaitGroup
var counter int
var mutex sync.Mutex
for i := 0; i < 10; i++ {
wg.Add(1)
go func() {
defer wg.Done()
mutex.Lock()
counter++
fmt.Println("Counter:", counter)
mutex.Unlock()
}()
}
wg.Wait()
}
在这个例子中,我们使用Mutex