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()
是否需要将其锁定?