在Go语言中,sync包提供了许多同步原语和锁,可以在并发编程中实现不同的控制并发的方式。下面是关于如何自由控制并发的示例详解。
使用WaitGroup控制并发执行
使用sync包的WaitGroup类型,可以实现并发执行多个任务,并等待所有任务完成后再执行后续操作的功能。WaitGroup内部有一个计数器,每增加一个goroutine,计数器加1,每个goroutine执行完之后会对计数器减1。当计数器的值变为0时,表示所有goroutine都执行完了。下面是一个使用WaitGroup控制并发执行的示例:
package main
import (
"fmt"
"sync"
"time"
)
func worker(id int, wg *sync.WaitGroup) {
fmt.Printf("Worker %d starting\n", id)
time.Sleep(time.Second)
fmt.Printf("Worker %d done\n", id)
wg.Done()
}
func main() {
var wg sync.WaitGroup
for i := 1; i <= 5; i++ {
wg.Add(1)
go worker(i, &wg)
}
wg.Wait()
fmt.Println("All workers done")
}
代码中定义了一个worker函数用于模拟任务执行,该函数接收一个等待组指针作为参数,任务执行完之后会调用等待组的Done方法。在main函数中,首先创建WaitGroup实例,并使用Add方法将执行的任务数加入到等待组中,然后启动goroutine执行worker函数。最后调用等待组的Wait方法,等待所有任务执行完毕。执行结果如下:
Worker 1 starting
Worker 2 starting
Worker 3 starting
Worker 4 starting
Worker 5 starting
Worker 4 done
Worker 2 done
Worker 3 done
Worker 5 done
Worker 1 done
All workers done
使用Mutex和Cond控制并发访问共享变量
在多个goroutine并发访问共享变量时,为了避免数据竞争和不一致性问题,可以使用sync包的Mutex和Cond类型进行控制。Mutex是一种互斥锁,可以保证同时只有一个goroutine访问共享资源。Cond是在Mutex的基础上实现的条件变量,可以使goroutine在满足特定条件时才继续执行。下面是一个使用Mutex和Cond控制并发访问共享变量的示例:
package main
import (
"fmt"
"sync"
)
var (
count int
mutex sync.Mutex
cond *sync.Cond = sync.NewCond(&mutex)
)
func producer() {
for i := 0; i < 10; i++ {
mutex.Lock()
count++
fmt.Println("Producer: Producing ", count)
cond.Signal()
mutex.Unlock()
}
}
func consumer() {
for i := 0; i < 10; i++ {
mutex.Lock()
for count == 0 {
cond.Wait()
}
count--
fmt.Println("Consumer: Consuming ", count)
mutex.Unlock()
}
}
func main() {
go consumer()
go producer()
time.Sleep(5 * time.Second)
}
代码中定义了一个共享变量count,两个goroutine分别为生产者和消费者角色。在生产者goroutine中,使用Mutex进行同步,每次将count值加1,并调用Cond的Signal方法发送信号给消费者goroutine,表示有新的资源产生。在消费者goroutine中,先获取Mutex的锁,判断count是否为0,如果是则调用Cond的Wait方法等待生产者像它发送信号,如果不是则消费资源,并将count值减1。执行结果如下:
Producer: Producing 1
Consumer: Consuming 0
Producer: Producing 1
Consumer: Consuming 0
Producer: Producing 1
Consumer: Consuming 0
Producer: Producing 1
Consumer: Consuming 0
Producer: Producing 2
Consumer: Consuming 1
Producer: Producing 3
Consumer: Consuming 2
Producer: Producing 4
Consumer: Consuming 3
Producer: Producing 5
Consumer: Consuming 4
Producer: Producing 6
Consumer: Consuming 5
Producer: Producing 7
Consumer: Consuming 6
Producer: Producing 8
Consumer: Consuming 7
Producer: Producing 9
Consumer: Consuming 8
Producer: Producing 10
Consumer: Consuming 9
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:GO中sync包自由控制并发示例详解 - Python技术站