MST

星途 面试题库

面试题:Go闭包在并发编程中的潜在问题与解决

在Go语言的并发编程环境下,闭包可能会带来哪些资源竞争或者数据一致性的问题?请举例说明,并阐述如何通过合适的同步机制(如互斥锁、通道等)来解决这些问题。
31.5万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

闭包在Go并发编程中可能出现的问题

  1. 资源竞争问题:当多个协程同时访问和修改闭包中引用的共享变量时,会出现资源竞争。例如:
package main

import (
    "fmt"
)

func main() {
    num := 0
    var funcs []func()
    for i := 0; i < 10; i++ {
       funcs = append(funcs, func() {
          num = num + 1
          fmt.Println(num)
       })
    }
    for _, f := range funcs {
       go f()
    }
    select {}
}

在上述代码中,多个协程同时修改num变量,由于没有同步机制,最终打印的结果是不确定的,这就是资源竞争。

  1. 数据一致性问题:同样由于多个协程对共享变量的并发访问,可能导致数据不一致。比如某个协程读取到的数据是部分修改后的状态,而不是完整修改后的数据。

使用同步机制解决问题

  1. 使用互斥锁(sync.Mutex
package main

import (
    "fmt"
    "sync"
)

func main() {
    num := 0
    var mu sync.Mutex
    var funcs []func()
    for i := 0; i < 10; i++ {
       funcs = append(funcs, func() {
          mu.Lock()
          num = num + 1
          fmt.Println(num)
          mu.Unlock()
       })
    }
    for _, f := range funcs {
       go f()
    }
    select {}
}

通过mu.Lock()mu.Unlock(),确保在同一时间只有一个协程能够访问和修改num变量,解决了资源竞争和数据一致性问题。

  1. 使用通道(chan
package main

import (
    "fmt"
)

func main() {
    num := 0
    ch := make(chan int)
    var funcs []func()
    for i := 0; i < 10; i++ {
       funcs = append(funcs, func() {
          ch <- 1
          num = num + 1
          fmt.Println(num)
          <-ch
       })
    }
    for _, f := range funcs {
       go f()
    }
    select {}
}

这里通过通道ch来控制协程对num变量的访问,每次只有一个协程能够进入修改num的代码块,从而解决资源竞争和数据一致性问题。