go同步编程

栏目: Go · 发布时间: 8年前

内容简介:函数write中的这条defer语句保证了在该函数被执行结束之前互斥锁mutex一定会被解锁。对于同一个读写锁来说,施加在它之上的读锁定可以有多个。因此,只有我们对互斥锁进行相同数量的读解锁,才能够让某一个相应的写锁定获得进行的机会。*sync.RWMutex类型都没有相应的方法让我们获得已进行的读锁定的数量,所以这里是很容易出现问题的。还好我们可以使用defer语句来尽量避免此类问题的发生。

锁

互斥锁

函数write中的这条defer语句保证了在该函数被执行结束之前互斥锁mutex一定会被解锁。

var mutex sync.Mutex
func write() {
mutex.Lock()
defer mutex.Unlock()
// 省略若干条语句
}
func repeatedlyLock() {
    var mutex sync.Mutex
    fmt.Println("Lock the lock. (G0)")
    mutex.Lock()
    fmt.Println("The lock is locked. (G0)")
    for i := 1; i <= 3; i++ {
        //开启3个协程,mutex已经锁定,所以程序会被阻塞。在unlock之后,随机启动一个。
        go func(i int) {
            //协程阻塞,只打印这一行。
            fmt.Printf("Lock the lock. (G%d)\n", i)
            mutex.Lock()
            fmt.Printf("The lock is locked. (G%d)\n", i)
        }(i)
    }

    time.Sleep(time.Second)
    fmt.Println("Unlock the lock. (G0)")
    mutex.Unlock()
    fmt.Println("The lock is unlocked. (G0)")
    time.Sleep(time.Second)
}

虽然互斥锁可以被直接的在多个Goroutine之间共享,但是我们还是强烈建议把对同一个互斥锁的成对的锁定和解锁操作放在同一个层次的代码块中。例如,在同一个函数或方法中对某个互斥锁的进行锁定和解锁。又例如,把互斥锁作为某一个结构体类型中的字段,以便在该类型的多个方法中使用它。

读写锁

  • 多个写操作之间都是互斥的.
  • 写操作与读操作之间也都是互斥的.
  • 多个读操作之间却不存在互斥关系.
func (*RWMutex) Lock //写锁定
func (*RWMutex) Unlock //写解锁
func (*RWMutex) RLock //读锁定
func (*RWMutex) RUnlock //读解锁

对于同一个读写锁来说,施加在它之上的读锁定可以有多个。因此,只有我们对互斥锁进行相同数量的读解锁,才能够让某一个相应的写锁定获得进行的机会。*sync.RWMutex类型都没有相应的方法让我们获得已进行的读锁定的数量,所以这里是很容易出现问题的。还好我们可以使用defer语句来尽量避免此类问题的发生。

package main
import (
    "sync"
    "time"
)

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 end")
}
package main
import (
    "sync"
    "time"
)
var m *sync.RWMutex
func main() {
    m = new(sync.RWMutex)
    //写的时候啥都不能干
    go write(1)
    go read(2)
    go write(3)
    time.Sleep(4 * 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 end")
}
//1 write end结束之后,2才能reading
//2 read end结束之后,3 才能writing
func write(i int) {
    println(i, "write start")
    m.Lock()
    println(i, "writing")
    time.Sleep(1 * time.Second)
    m.Unlock()
    println(i, "write end")
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。

Charlotte's Web

Charlotte's Web

E. B. White / Scholastic / 2004 / USD 0.01

This is the tale of how a little girl named Ferm, with the help of a friendly spider, saved her pig, Wilbur, from the usual fate of nice fat little pigs.一起来看看 《Charlotte's Web》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具