golang基础-互斥锁、读写锁

互斥锁

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

package main

import(
    "fmt"
    "time"
    "sync"
    "math/rand"
)

var lock sync.Mutex

func 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)
}

  • 19
  • 20
  • 21
  • 22
  • 2

输出如下:

PS E:\golang\go_pro\src\safly> go run demo.go
map[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 main

import(
    // "fmt"
    "time"
    "sync"

)

var m *sync.RWMutex

func 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.go
1 read start
1 reading
1 read over
2 read start
2 reading
2 read over

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

猜你喜欢

转载自blog.csdn.net/feiwutudou/article/details/80913649
今日推荐