golang 协程共享数据
时间: 2023-09-28 09:07:20 浏览: 438
在 Golang 中,协程之间的数据共享可以通过共享内存的方式实现。但是需要注意的是,多个协程同时访问同一个共享变量时,可能会出现竞态条件(race condition)导致数据不一致的问题。
为了避免这种问题,Golang 提供了一些同步机制,如互斥锁(Mutex)、读写锁(RWMutex)和信道(Channel)等。
互斥锁是最基本的同步机制,它可以保证同时只有一个协程访问共享变量。当一个协程获得了互斥锁,其他协程就必须等待该协程释放互斥锁后才能访问共享变量。示例代码如下:
```go
var mu sync.Mutex // 互斥锁
var count int // 共享变量
func increment() {
mu.Lock() // 获得互斥锁
defer mu.Unlock() // 在函数退出时释放互斥锁
count++
}
func main() {
for i := 0; i < 1000; i++ {
go increment()
}
time.Sleep(time.Second)
fmt.Println(count) // 输出 1000
}
```
读写锁是一种更高级的同步机制,它允许多个协程同时读取共享变量,但只允许一个协程写入共享变量。这样可以提高读取效率,同时保证数据一致性。示例代码如下:
```go
var rwmu sync.RWMutex // 读写锁
var count int // 共享变量
func increment() {
rwmu.Lock() // 获得写锁
defer rwmu.Unlock() // 在函数退出时释放锁
count++
}
func read() {
rwmu.RLock() // 获得读锁
defer rwmu.RUnlock() // 在函数退出时释放锁
fmt.Println(count)
}
func main() {
for i := 0; i < 1000; i++ {
go increment()
}
for i := 0; i < 10; i++ {
go read()
}
time.Sleep(time.Second)
}
```
信道是一种更高级的同步机制,它可以让协程之间进行通信,同时避免竞态条件的问题。通过信道,一个协程可以向另一个协程发送数据,或者从另一个协程接收数据,这样就可以避免多个协程同时访问同一个共享变量的问题。示例代码如下:
```go
var wg sync.WaitGroup
func worker(id int, jobs <-chan int, results chan<- int) {
defer wg.Done()
for j := range jobs {
fmt.Printf("worker %d started job %d\n", id, j)
time.Sleep(time.Second)
fmt.Printf("worker %d finished job %d\n", id, j)
results <- j * 2
}
}
func main() {
jobs := make(chan int, 100)
results := make(chan int, 100)
for w := 1; w <= 3; w++ {
wg.Add(1)
go worker(w, jobs, results)
}
for j := 1; j <= 9; j++ {
jobs <- j
}
close(jobs)
for a := 1; a <= 9; a++ {
<-results
}
wg.Wait()
}
```
以上是几种常见的 Golang 协程共享数据的方式,具体使用时需要根据实际情况选择合适的同步机制。
阅读全文