10.5.2 sync.RWMutex类型
sync.RWMutex
类型是另外一种互斥体,它是 sync.Mutex
的改进版,在 sync
目录的 rwmutex.go
文件中定义如下:
换句话说,sync.RWMutex
是基于 sync.Mutex
做了必要的添加和改进。
现在让我们来说说 sync.RWMutex
是如果改进 sync.Mutex
的。尽管使用 sync.RWMutex
互斥锁只允许有一个函数执行写操作,但您能有多个属于 sync.RWMutex
互斥锁的读取者。然而,有一件事您要注意:除非sync.RWMutex
互斥锁的所有读取者解锁,您不能为写操作给它上锁,这也是为了实现多互斥锁读取而付出的代价。
RLock()
和 RUnlock()
是出于读取的目的帮您与 sync.RWMutex
互斥体工作的函数,它们分别用于上锁和解锁互斥体。当您为了写操作想要上锁和解锁一个 sync.RWMutex
互斥体时,用在 sync.Mutex
互斥体的 Lock()
和 Unlock()
函数仍适用。因此为了读操作 RLock()
函数应该与 RUnlock()
配对调用。最后,显而易见,您不应该修改在 RLock()
和 RUnlock()
代码块间的任何共享变量。
rwMutex.go
代码说明了 sync.RWMutex
类型的使用和通途。程序分六部分介绍,并且相同的函数有俩个稍有不同的版本。第一个为读操作使用 sync.RWMutex
互斥体,第二个为读操作使用 sync.Mutex
互斥体。这两个函数之间的不同表现会帮助您理解为了读取操作使用 sync.RWMutex
互斥体的好处更多。
rwMutex.go
的第一部分如下:
secret
结构有一个共享变量,一个 sync.RWMutex
互斥锁和一个 sync.Mutex
互斥锁。
rwMutex.go
的第二段代码如下:
Change()
函数修改共享变量,意味着您需要使用一个排他锁,这就是使用 Lock()
和 Unlock()
函数的原因。当做变更时离不开使用排他锁!
rwMutex.go
的第三部分如下:
show()
函数使用 RLock()
和 RUnlock()
函数是因为它的关键部分是用来读取共享变量的。因此,尽管 goroutines 能够读取共享变量,但是在不使用 Lock()
和 Unlock()
函数的情况下,所有 goroutines 都不能修改共享变量。但是,只要有人使用互斥锁读取共享变量,Lock()
函数就会被一直阻塞。
rwMutex.go
的第四段代码如下:
showWithLock()
函数和 show()
函数之间唯一的不同是 showWithLock()
函数为了读操作使用了排他锁,这意味着只有一个 showWithLock()
函数能读取 secret
结构体的 password
字段。
rwMutex.go
的第五段代码如下:
rwMutex.go
的其余代码如下:
执行 rwMutex.go
两次并使用 time(1)
命令行工具测试这个程序的两个版本将产生如下输出:
注意上面命令结尾处的 > /dev/null
是为了忽略这两个命令的输出。因此,使用 sync.RWMutex
互斥体的版本要比使用 sync.Mutex
的版本快很多。
Last updated