为了账号安全,请及时绑定邮箱和手机立即绑定

在多个 goroutine 之间共享的 Golang struct 中,非共享成员是否需要互斥保护?

在多个 goroutine 之间共享的 Golang struct 中,非共享成员是否需要互斥保护?

Go
慕姐8265434 2021-12-07 16:44:43
我在多个 goroutine 之间共享了一个 Golang 结构。对于结构成员的并发访问,有互斥锁sync.RWMutex。对于单个 goroutine 访问的 struct 成员,是否需要互斥保护?例如,在下面的代码中,一个单独的 writer goroutine 访问成员 shared.exclusiveCounter,没有任何锁保护。这是正确的/安全的吗?或者是否需要互斥锁,因为多个 goroutine 通过共享指针访问整个结构?package mainimport (    "fmt"    "sync"    "time")func main() {    s := &shared{mutex: &sync.RWMutex{}}    readerDone := make(chan int)    writerDone := make(chan int)    go reader(s, readerDone)    go writer(s, writerDone)    <-readerDone    <-writerDone}type shared struct {    mutex            *sync.RWMutex    sharedCounter    int // member shared between multiple goroutines, protected by mutex    exclusiveCounter int // member exclusive of one goroutine -- is mutex needed?}func (s *shared) readCounter() int {    defer s.mutex.RUnlock()    s.mutex.RLock()    return s.sharedCounter}func (s *shared) setCounter(i int) {    defer s.mutex.Unlock()    s.mutex.Lock()    s.sharedCounter = i}func reader(s *shared, done chan<- int) {    for {        time.Sleep(2 * time.Second)        counter := s.readCounter()        fmt.Printf("reader: read counter=%d\n", counter)        if counter > 5 {            break        }    }    fmt.Printf("reader: exiting\n")    done <- 1}func writer(s *shared, done chan<- int) {    s.exclusiveCounter = 0    for {        time.Sleep(1 * time.Second)        s.exclusiveCounter++        fmt.Printf("writer: writing counter=%d\n", s.exclusiveCounter)        s.setCounter(s.exclusiveCounter)        if s.exclusiveCounter > 5 {            break        }    }    fmt.Printf("writer: exiting\n")    done <- 1}
查看完整描述

2 回答

?
婷婷同学_

TA贡献1844条经验 获得超8个赞

如果只有一个 goroutine 访问 struct 成员,则不需要使用互斥锁来控制访问。无论如何,我可能会使用一个(或者重新使用结构中现有的互斥锁,或者另一个),因为虽然今天可能只有一个 goroutine 访问该结构成员,但没有什么强制执行的。


查看完整回答
反对 回复 2021-12-07
?
素胚勾勒不出你

TA贡献1827条经验 获得超9个赞

你不需要另一个互斥锁,如果你只是在 int* 类型上操作,你可以一起抛弃互斥锁并使用 atomic.*


type shared struct {

    sharedCounter    int64 // member shared between multiple goroutines, protected by mutex

    exclusiveCounter int64 // member exclusive of one goroutine -- is mutex needed?

}


func (s *shared) readCounter() int64 {

    return atomic.LoadInt64(&s.sharedCounter)

}


func (s *shared) setCounter(i int64) {

    atomic.StoreInt64(&s.sharedCounter, i)

}


查看完整回答
反对 回复 2021-12-07
  • 2 回答
  • 0 关注
  • 178 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信