go同步编程

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

内容简介:函数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")
}

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

查看所有标签

猜你喜欢:

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

游戏编程算法与技巧

游戏编程算法与技巧

【美】Sanjay Madhav / 刘瀚阳 / 电子工业出版社 / 2016-10 / 89

《游戏编程算法与技巧》介绍了大量今天在游戏行业中用到的算法与技术。《游戏编程算法与技巧》是为广大熟悉面向对象编程以及基础数据结构的游戏开发者所设计的。作者采用了一种独立于平台框架的方法来展示开发,包括2D 和3D 图形学、物理、人工智能、摄像机等多个方面的技术。《游戏编程算法与技巧》中内容几乎兼容所有游戏,无论这些游戏采用何种风格、开发语言和框架。 《游戏编程算法与技巧》的每个概念都是用C#......一起来看看 《游戏编程算法与技巧》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

随机密码生成器
随机密码生成器

多种字符组合密码

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码