- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我正在尝试构建 map 。通常所有读取都可以并行完成,除非写入时,所有读取都需要锁定。我以为我了解 Mutex 在 go 中的工作原理,但显然我不了解。
我首先尝试使用 RWMutex 写锁:
type person struct {
sync.RWMutex
age int
}
func main() {
a := person{age: 3}
fmt.Println(a.age)
go func() {
a.Lock()
time.Sleep(5 * time.Second)
a.age = 4
fmt.Println(a.age)
a.Unlock()
}()
fmt.Println(a.age)
fmt.Println("main", a.age)
time.Sleep(20 * time.Second)
}
我有点期待写锁会把读操作锁上a.age。相反,我得到了:
3
3
main 3
4
所以我决定也添加一个读锁:
func main() {
a := person{age: 3}
fmt.Println(a.age)
go func() {
a.Lock()
a.RLock()
time.Sleep(5 * time.Second)
a.age = 4
fmt.Println(a.age)
a.Unlock()
a.RUnlock()
}()
fmt.Println(a.age)
fmt.Println("main", a.age)
time.Sleep(20 * time.Second)
}
更糟糕的是,我得到了:
3
3
main 3
显然我不明白这是如何工作的。感谢您的帮助。
最佳答案
切勿双锁。您的问题是您没有将 main
末尾的读取包装在锁中 - 如果他们不尝试建立锁,则没有什么可以阻止他们在其他东西写入时读取(甚至如果写入正在使用锁)。锁本身就是提供互斥 (MutEx) 的东西,因此只有持续使用它才能获得它:
func main() {
a := person{age: 3}
fmt.Println(a.age)
go func() {
a.Lock()
time.Sleep(5 * time.Second)
a.age = 4
fmt.Println(a.age)
a.Unlock()
}()
a.RLock()
fmt.Println(a.age)
fmt.Println("main", a.age)
a.RUnlock()
time.Sleep(20 * time.Second)
}
这里没有魔法发生;实际上是调用 Lock
和 RLock
来进行锁定。如果您不调用它们,则不会阻止并发访问。当您调用 Lock
时,它会一直等到它可以完全锁定自己,然后锁定它并返回。当您调用 RLock
时,它会等待直到没有写锁,然后获取一个(共享的)读锁。它正在调用那些提供互斥的函数,而不是幕后发生的任何魔法。
关于go - 对 Go 中的 Locks/Mutex 感到困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49201112/
我正在尝试学习Rust。我正在阅读一本书online,该书实现了unix程序cat。现在,我试图读取作为像cargo run file1.txt file2.txt这样的参数传递的文件的内容,但是程序
我在 GHC 8.0.1 中遇到了一个带有种类索引 (?) GADT 的奇怪情况,其中在类型与种类签名中引入 foralls 会产生不同的类型检查行为。 考虑以下数据类型: {-# LANGUAGE
我正在使用 Perl 5.10 开发应用程序,HTML::Mason和 Apache 2.2。这是我第一次在大型项目中使用 Perl 5.10。我每隔一段时间就会出现奇怪的行为。应用程序因一个非常奇怪
我正在尝试将文件上传到aws中的rust中,因为我使用的是 rusoto_s3 的s3 rust客户端,当这些部分从单个线程发送时,我设法使分段上传代码正常工作不是我想要的,我想上传大文件,并且希望能
我是一名优秀的程序员,十分优秀!