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

我在多个 goroutine 之间共享了一个 Golang 结构。对于结构成员的并发访问,有互斥锁sync.RWMutex。对于单个 goroutine 访问的 struct 成员,是否需要互斥保护?


例如,在下面的代码中,一个单独的 writer goroutine 访问成员 shared.exclusiveCounter,没有任何锁保护。这是正确的/安全的吗?或者是否需要互斥锁,因为多个 goroutine 通过共享指针访问整个结构?


package main


import (

    "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

}


慕姐8265434
浏览 179回答 2
2回答

婷婷同学_

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

素胚勾勒不出你

你不需要另一个互斥锁,如果你只是在 int* 类型上操作,你可以一起抛弃互斥锁并使用 atomic.*type shared struct {&nbsp; &nbsp; sharedCounter&nbsp; &nbsp; int64 // member shared between multiple goroutines, protected by mutex&nbsp; &nbsp; exclusiveCounter int64 // member exclusive of one goroutine -- is mutex needed?}func (s *shared) readCounter() int64 {&nbsp; &nbsp; return atomic.LoadInt64(&s.sharedCounter)}func (s *shared) setCounter(i int64) {&nbsp; &nbsp; atomic.StoreInt64(&s.sharedCounter, i)}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go