golang基础-互斥锁、读写锁

来源:互联网 发布:ubuntu 15.10 163源 编辑:程序博客网 时间:2024/06/03 17:11

互斥锁

其中Mutex为互斥锁,Lock()加锁,Unlock()解锁,使用Lock()加锁后,便不能再次对其进行加锁,直到利用Unlock()解锁对其解锁后,才能再次加锁.适用于读写不确定场景,即读写次数没有明显的区别,并且只允许只有一个读或者写的场景,所以该锁叶叫做全局锁。
func (m *Mutex) Unlock()用于解锁m,如果在使用Unlock()前未加锁,就会引起一个运行错误.已经锁定的Mutex并不与特定的goroutine相关联,这样可以利用一个goroutine对其加锁,再利用其他goroutine对其解锁。

package mainimport(    "fmt"    "time"    "sync"    "math/rand")var lock sync.Mutexfunc main() {    testMap()}func testMap() {    var a map[int]int    a = make(map[int]int, 5)    a[8] = 10    a[3] = 10    a[2] = 10    a[1] = 10    a[18] = 10    for i := 0; i < 2; i++ {        go func(b map[int]int) {            lock.Lock()            b[8] = rand.Intn(100)            lock.Unlock()        }(a)    }    lock.Lock()    fmt.Println(a)    lock.Unlock()    time.Sleep(time.Second)    fmt.Println(a)}

输出如下:

PS E:\golang\go_pro\src\safly> go run demo.gomap[3:10 2:10 1:10 18:10 8:10]map[2:10 1:10 18:10 8:87 3:10]PS E:\golang\go_pro\src\safly>

我们利用了time.Sleep(time.Second)这个进行的延迟,goroute执行完毕,就进行输出,结果是进行了map的修改

读写锁

读写锁实际是一种特殊的自旋锁,它把对共享资源的访问者划分成读者和写者,读者只对共享资源进行读访问,写者则需要对共享资源进行写操作。这种锁相对于自旋锁而言,能提高并发性,因为在多处理器系统中,它允许同时有多个读者来访问共享资源,最大可能的读者数为实际的逻辑CPU数。写者是排他性的,一个读写锁同时只能有一个写者或多个读者(与CPU数相关),但不能同时既有读者又有写者。

1、可以随便读,多个goroutine同时读

package mainimport(    // "fmt"    "time"    "sync")var m *sync.RWMutexfunc main() {    m = new(sync.RWMutex)    // 多个同时读    go read(1)    go read(2)    time.Sleep(2*time.Second)}func read(i int) {    println(i,"read start")    m.RLock()    println(i,"reading")    time.Sleep(1*time.Second)    m.RUnlock()        println(i,"read over")}

输出如下:

PS E:\golang\go_pro\src\safly> go run demo.go1 read start1 reading1 read over2 read start2 reading2 read over

可以看出1 读还没有结束,2已经在读

原创粉丝点击