Golang:具有只读访问权限的包作用域变量是否需要互斥锁?

Golang:具有只读访问权限的包作用域变量是否需要互斥锁?,go,Go,如果我有一个包作用域变量,如下所示: var ( bus *Bus // THIS VARIABLE ) // Bus represents a repository bus. This contains all of the repositories. type Bus struct { UserRepository *UserRepository // ... } …我允许访问存储库中的总线变量,以便它们可以相互访问,如果它们可以同时使用,我需要使用任何类型的互斥

如果我有一个包作用域变量,如下所示:

var (
    bus *Bus // THIS VARIABLE
)

// Bus represents a repository bus. This contains all of the repositories.
type Bus struct {
    UserRepository *UserRepository
    // ...
}
…我允许访问存储库中的
总线
变量,以便它们可以相互访问,如果它们可以同时使用,我需要使用任何类型的互斥吗

将发生什么的快速伪代码:

// Router
router.GET("/user/:id", c.FindUser)

// Controller
func (c *UserController) FindUser(w http.ResponesWriter, r *http.Request) {
    w.Write([]byte(c.UserService.FindUser(r.Get("id"))))
}

// Service
func (s UserService) FindUser(id int) *domain.User {
    return s.UserRepository.FindByID(id) 
}

// Repository
func (r UserRepository) FindByID(id int) *domain.User {
    // This is where the package-scope `bus` variable will be used
}

FindByID
函数中,我可以使用包作用域
bus
变量,当然可以并发访问该变量,因为每当HTTP请求触发它时就会调用它,而这些都是并发处理的。

如果您所做的只是读取变量的内容,那么不需要互斥锁。然而,如果你改变了它的状态,那么你需要保护它

两次并发写入或并发写入和读取可能会导致问题。如果你写的东西很少,你可能想用。它将允许多个读卡器访问,但不能与一个写卡器一起访问


还有,看看。它是尽力而为的检测器,所以它不能保证您没有竞争条件,但它可以检测一些用例。还要注意的是,为了让race检测器检测到它,您需要引起race,因此必须同时使用
总线或模拟真实条件来编写测试。

如果您所做的只是读取变量的内容,那么不,您不需要互斥锁。然而,如果你改变了它的状态,那么你需要保护它

两次并发写入或并发写入和读取可能会导致问题。如果你写的东西很少,你可能想用。它将允许多个读卡器访问,但不能与一个写卡器一起访问


还有,看看。它是尽力而为的检测器,所以它不能保证您没有竞争条件,但它可以检测一些用例。还要注意,为了让race detector检测到它,您需要引起race,因此必须同时使用
总线或模拟真实条件来编写测试。

您可以从一个值中读取多个goroutine,但如何将其用于任何事情呢?它从来没有被编写过吗?规则很简单,如果存在并发写入,或者任何值的并发读取和写入,都需要同步。我使用SQL驱动程序进行实际写入。但是
bus
变量本质上是一个工厂,它包含了许多方法,这些方法是实际SQL实现的包装,SQL驱动程序处理它自己的并发规则,所以我不必担心这一点。如果您所做的只是从DB读写,那么不,您不需要互斥锁。但是,如果在这个过程中写入了任何内部变量,那么它们(或整个总线)将需要被锁定。例如,如果您碰巧有一个内部计数器,用于计算通过总线执行的读取次数,那么这将需要一个互斥锁。@RayfenWindspear如果包变量是一个类似
var catList[]*model.Cat
的指针,那么在其他函数中,我使用gorm填充数据,
catList,=model.Cat{}.All()
是否需要锁定它?可以从一个值中读取多个goroutine,但如果它从未写入,如何将其用于任何用途?规则很简单,如果存在并发写入,或者任何值的并发读取和写入,都需要同步。我使用SQL驱动程序进行实际写入。但是
bus
变量本质上是一个工厂,它包含了许多方法,这些方法是实际SQL实现的包装,SQL驱动程序处理它自己的并发规则,所以我不必担心这一点。如果您所做的只是从DB读写,那么不,您不需要互斥锁。但是,如果在这个过程中写入了任何内部变量,那么它们(或整个总线)将需要被锁定。例如,如果您碰巧有一个内部计数器,用于计算通过总线执行的读取次数,那么这将需要一个互斥锁。@RayfenWindspear如果包变量是一个类似
var catList[]*model.Cat
的指针,那么在其他函数中,我使用gorm填充数据,
catList,=model.Cat{}.All()
是否需要将其锁定?