Golang 开发者GolangGo

golang 中 sync.Mutex 和 sync.RWMut

2017-07-31  本文已影响1630人  WangZZ

介绍

golang 中的 sync 包实现了两种锁:

Mutex(互斥锁)

示例

加锁和解锁示例

package main

import (
    "time"
    "fmt"
    "sync"
)

func main() {
    var mutex sync.Mutex
    fmt.Println("Lock the lock")
    mutex.Lock()
    fmt.Println("The lock is locked")
    channels := make([]chan int, 4)
    for i := 0; i < 4; i++ {
        channels[i] = make(chan int)
        go func(i int, c chan int) {
            fmt.Println("Not lock: ", i)
            mutex.Lock()
            fmt.Println("Locked: ", i)
            time.Sleep(time.Second)
            fmt.Println("Unlock the lock: ", i)
            mutex.Unlock()
            c <- i
        }(i, channels[i])
    }
    time.Sleep(time.Second)
    fmt.Println("Unlock the lock")
    mutex.Unlock()
    time.Sleep(time.Second)

    for _, c := range channels {
        <-c
    }
}

程序输出:

Lock the lock
The lock is locked
Not lock:  1
Not lock:  2
Not lock:  0
Not lock:  3
Unlock the lock
Locked:  1
Unlock the lock:  1
Locked:  2
Unlock the lock:  2
Locked:  3
Unlock the lock:  3
Locked:  0
Unlock the lock:  0

在解锁之前加锁会导致死锁

package main

import (
    "fmt"
    "sync"
)

func main(){
    var mutex sync.Mutex
    mutex.Lock()
    fmt.Println("Locked")
    mutex.Lock()
}

程序输出:

Locked
fatal error: all goroutines are asleep - deadlock!

RWMutex(读写锁)

Lock() 和 Unlock()

RLock() 和 RUnlock()

示例

Lock() 和 Unlock()

package main

import (
    "sync"
    "fmt"
    "time"
)

func main() {
    var mutex *sync.RWMutex
    mutex = new(sync.RWMutex)
    fmt.Println("Lock the lock")
    mutex.Lock()
    fmt.Println("The lock is locked")

    channels := make([]chan int, 4)
    for i := 0; i < 4; i++ {
        channels[i] = make(chan int)
        go func(i int, c chan int) {
            fmt.Println("Not lock: ", i)
            mutex.Lock()
            fmt.Println("Locked: ", i)
            fmt.Println("Unlock the lock: ", i)
            mutex.Unlock()
            c <- i
        }(i, channels[i])
    }
    time.Sleep(time.Second)
    fmt.Println("Unlock the lock")
    mutex.Unlock()
    time.Sleep(time.Second)

    for _, c := range channels {
        <-c
    }
}

程序输出:

Lock the lock
The lock is locked
Not lock:  0
Not lock:  1
Not lock:  2
Not lock:  3
Unlock the lock
Locked:  0
Unlock the lock:  0
Locked:  2
Unlock the lock:  2
Locked:  3
Unlock the lock:  3
Locked:  1
Unlock the lock:  1

Lock() 和 RLock()

package main

import (
    "sync"
    "fmt"
    "time"
)

func main() {
    var mutex *sync.RWMutex
    mutex = new(sync.RWMutex)
    fmt.Println("Lock the lock")
    mutex.Lock()
    fmt.Println("The lock is locked")

    channels := make([]chan int, 4)
    for i := 0; i < 4; i++ {
        channels[i] = make(chan int)
        go func(i int, c chan int) {
            fmt.Println("Not read lock: ", i)
            mutex.RLock()
            fmt.Println("Read Locked: ", i)
            fmt.Println("Unlock the read lock: ", i)
            time.Sleep(time.Second)
            mutex.RUnlock()
            c <- i
        }(i, channels[i])
    }
    time.Sleep(time.Second)
    fmt.Println("Unlock the lock")
    mutex.Unlock()
    time.Sleep(time.Second)

    for _, c := range channels {
        <-c
    }
}

程序输出:

Lock the lock
The lock is locked
Not read lock:  2
Not read lock:  3
Not read lock:  1
Not read lock:  0
Unlock the lock
Read Locked:  2
Read Locked:  1
Unlock the read lock:  2
Unlock the read lock:  1
Read Locked:  0
Read Locked:  3
Unlock the read lock:  0
Unlock the read lock:  3

Unlock() 使用之前不存在 Lock()

package main

import (
    "sync"
)

func main(){
    var rwmutex *sync.RWMutex
    rwmutex = new(sync.RWMutex)
    rwmutex.Unlock()
}

程序输出:

panic: sync: Unlock of unlocked RWMutex

RWMutex 使用不当导致的死锁

示例1:

package main

import (
    "sync"
)

func main(){
    var rwmutex *sync.RWMutex
    rwmutex = new(sync.RWMutex)
    rwmutex.Lock()
    rwmutex.Lock()
}

程序输出:

fatal error: all goroutines are asleep - deadlock!

示例2:

package main

import (
    "sync"
)

func main(){
    var rwmutex *sync.RWMutex
    rwmutex = new(sync.RWMutex)
    rwmutex.Lock()
    rwmutex.RLock()
}

程序输出:

fatal error: all goroutines are asleep - deadlock!

RUnlock() 之前不存在 RLock()

package main

import (
    "sync"
)

func main(){
    var rwmutex *sync.RWMutex
    rwmutex = new(sync.RWMutex)
    rwmutex.RUnlock()
}

程序输出:

panic: sync: RUnlock of unlocked RWMutex

RUnlock() 个数多于 RLock()

package main

import (
    "sync"
)

func main(){
    var rwmutex *sync.RWMutex
    rwmutex = new(sync.RWMutex)
    rwmutex.RLock()
    rwmutex.RLock()
    rwmutex.RUnlock()
    rwmutex.RUnlock()
    rwmutex.RUnlock()
}

程序输出:

panic: sync: RUnlock of unlocked RWMutex
上一篇 下一篇

猜你喜欢

热点阅读