在Debian下使用Go语言进行并发编程,主要依赖于Go的轻量级线程——goroutines和通道(channels)。以下是一些基本的并发编程概念和实践:
Goroutines是Go语言中实现并发的基本单元。它们非常轻量级,启动速度快,且占用的内存很少。
创建goroutine:
go func() {
// 这里是你想要并发执行的代码
}()
示例:
package main
import (
"fmt"
"time"
)
func printNumbers() {
for i := 1; i <= 5; i++ {
fmt.Println(i)
time.Sleep(1 * time.Second)
}
}
func main() {
go printNumbers() // 启动一个新的goroutine
time.Sleep(6 * time.Second) // 主线程等待足够的时间以便goroutine完成
}
Channels是用于在goroutines之间进行通信和同步的机制。它们可以用来传递数据,也可以用来协调goroutines的执行。
创建channel:
ch := make(chan int) // 创建一个整型channel
发送和接收数据:
ch <- 42 // 发送数据到channel
value := <-ch // 从channel接收数据
示例:
package main
import (
"fmt"
"time"
)
func worker(done chan bool) {
fmt.Println("working...")
time.Sleep(time.Second)
fmt.Println("done")
done <- true // 通知主线程工作已完成
}
func main() {
done := make(chan bool) // 创建一个布尔型channel
go worker(done) // 启动worker goroutine
<-done // 等待worker完成
}
除了channels,Go还提供了其他同步机制,如sync.WaitGroup、sync.Mutex等。
sync.WaitGroup: 用于等待一组goroutines完成。
示例:
package main
import (
"fmt"
"sync"
"time"
)
func worker(id int, wg *sync.WaitGroup) {
defer wg.Done() // 在函数结束时调用Done()来通知WaitGroup
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)
}
wg.Wait() // 等待所有goroutines完成
}
sync.Mutex: 用于保护共享资源,防止数据竞争。
示例:
package main
import (
"fmt"
"sync"
)
var (
counter int
mutex sync.Mutex
)
func increment() {
mutex.Lock() // 加锁
counter++ // 修改共享资源
mutex.Unlock() // 解锁
}
func main() {
var wg sync.WaitGroup
for i := 0; i < 1000; i++ {
wg.Add(1)
go func() {
defer wg.Done()
increment()
}()
}
wg.Wait()
fmt.Println("Counter:", counter)
}
在Debian下使用Go语言进行并发编程,主要依赖于goroutines和channels。通过合理使用这些机制,可以轻松实现高效的并发程序。同时,结合sync.WaitGroup和sync.Mutex等同步工具,可以更好地管理goroutines之间的协作和资源共享。